Micron Document
--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
| SparkN0de-git | SparkN0de |
--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------

Node / ReticulumProjects / MeshChatX.git / files / meshchatx / src / backend / identity_context.py

Displaying Raw • Download


meshchatx/src/backend/identity_context.py fa46dc4ce9ab50cbe66a7a9e4b3bca0140102345 (fa46dc4c) Text, 41.43 KB

T8b949e# SPDX-License-Identifier: 0BSD

Tff7b72import T7ee787asyncio
Tff7b72import T7ee787contextlib
Tff7b72import T7ee787os
Tff7b72import T7ee787threading

Tff7b72import T7ee787RNS

Tff7b72from T7ee787meshchatxT7ee787.T7ee787srcT7ee787.T7ee787backendT7ee787.T7ee787announce_handler Tff7b72import Te6edf3AnnounceHandler
Tff7b72from T7ee787meshchatxT7ee787.T7ee787srcT7ee787.T7ee787backendT7ee787.T7ee787announce_manager Tff7b72import Te6edf3AnnounceManager
Tff7b72from T7ee787meshchatxT7ee787.T7ee787srcT7ee787.T7ee787backendT7ee787.T7ee787archiver_manager Tff7b72import Te6edf3ArchiverManager
Tff7b72from T7ee787meshchatxT7ee787.T7ee787srcT7ee787.T7ee787backendT7ee787.T7ee787auto_propagation_manager Tff7b72import Te6edf3AutoPropagationManager
Tff7b72from T7ee787meshchatxT7ee787.T7ee787srcT7ee787.T7ee787backendT7ee787.T7ee787bot_handler Tff7b72import Te6edf3BotHandler
Tff7b72from T7ee787meshchatxT7ee787.T7ee787srcT7ee787.T7ee787backendT7ee787.T7ee787community_interfaces Tff7b72import Te6edf3CommunityInterfacesManager
Tff7b72from T7ee787meshchatxT7ee787.T7ee787srcT7ee787.T7ee787backendT7ee787.T7ee787config_manager Tff7b72import Te6edf3ConfigManager
Tff7b72from T7ee787meshchatxT7ee787.T7ee787srcT7ee787.T7ee787backendT7ee787.T7ee787database Tff7b72import Te6edf3Database
Tff7b72from T7ee787meshchatxT7ee787.T7ee787srcT7ee787.T7ee787backendT7ee787.T7ee787docs_manager Tff7b72import Te6edf3DocsManager
Tff7b72from T7ee787meshchatxT7ee787.T7ee787srcT7ee787.T7ee787backendT7ee787.T7ee787forwarding_manager Tff7b72import Te6edf3ForwardingManager
Tff7b72from T7ee787meshchatxT7ee787.T7ee787srcT7ee787.T7ee787backendT7ee787.T7ee787integrity_manager Tff7b72import Tb4b4b4(
Te6edf3CriticalIntegrityErrorTb4b4b4,
Te6edf3IntegrityManagerTb4b4b4,
Te6edf3select_critical_integrity_issuesTb4b4b4,
Tb4b4b4)
Tff7b72from T7ee787meshchatxT7ee787.T7ee787srcT7ee787.T7ee787backendT7ee787.T7ee787map_manager Tff7b72import Te6edf3MapManager
Tff7b72from T7ee787meshchatxT7ee787.T7ee787srcT7ee787.T7ee787backendT7ee787.T7ee787map_overlay_manager Tff7b72import Te6edf3MapOverlayManager
Tff7b72from T7ee787meshchatxT7ee787.T7ee787srcT7ee787.T7ee787backendT7ee787.T7ee787meshchat_utils Tff7b72import Te6edf3create_lxmf_router
Tff7b72from T7ee787meshchatxT7ee787.T7ee787srcT7ee787.T7ee787backendT7ee787.T7ee787message_handler Tff7b72import Te6edf3MessageHandler
Tff7b72from T7ee787meshchatxT7ee787.T7ee787srcT7ee787.T7ee787backendT7ee787.T7ee787nomadnet_utils Tff7b72import Te6edf3NomadNetworkManager
Tff7b72from T7ee787meshchatxT7ee787.T7ee787srcT7ee787.T7ee787backendT7ee787.T7ee787repository_server_manager Tff7b72import Te6edf3RepositoryServerManager
Tff7b72from T7ee787meshchatxT7ee787.T7ee787srcT7ee787.T7ee787backendT7ee787.T7ee787ringtone_manager Tff7b72import Te6edf3RingtoneManager
Tff7b72from T7ee787meshchatxT7ee787.T7ee787srcT7ee787.T7ee787backendT7ee787.T7ee787rncp_handler Tff7b72import Te6edf3RNCPHandler
Tff7b72from T7ee787meshchatxT7ee787.T7ee787srcT7ee787.T7ee787backendT7ee787.T7ee787rnpath_handler Tff7b72import Te6edf3RNPathHandler
Tff7b72from T7ee787meshchatxT7ee787.T7ee787srcT7ee787.T7ee787backendT7ee787.T7ee787rnpath_trace_handler Tff7b72import Te6edf3RNPathTraceHandler
Tff7b72from T7ee787meshchatxT7ee787.T7ee787srcT7ee787.T7ee787backendT7ee787.T7ee787rnprobe_handler Tff7b72import Te6edf3RNProbeHandler
Tff7b72from T7ee787meshchatxT7ee787.T7ee787srcT7ee787.T7ee787backendT7ee787.T7ee787rnsh_manager Tff7b72import Te6edf3RNSHManager
Tff7b72from T7ee787meshchatxT7ee787.T7ee787srcT7ee787.T7ee787backendT7ee787.T7ee787rns_filesync_handler Tff7b72import Te6edf3RnsFilesyncHandler
Tff7b72from T7ee787meshchatxT7ee787.T7ee787srcT7ee787.T7ee787backendT7ee787.T7ee787rnstatus_handler Tff7b72import Te6edf3RNStatusHandler
Tff7b72from T7ee787meshchatxT7ee787.T7ee787srcT7ee787.T7ee787backendT7ee787.T7ee787rnx_manager Tff7b72import Te6edf3RNXManager
Tff7b72from T7ee787meshchatxT7ee787.T7ee787srcT7ee787.T7ee787backendT7ee787.T7ee787rrc Tff7b72import Te6edf3RRCManagerTb4b4b4, Te6edf3RRCServerManager
Tff7b72from T7ee787meshchatxT7ee787.T7ee787srcT7ee787.T7ee787backendT7ee787.T7ee787telephone_manager Tff7b72import Te6edf3TelephoneManager
Tff7b72from T7ee787meshchatxT7ee787.T7ee787srcT7ee787.T7ee787backendT7ee787.T7ee787translator_handler Tff7b72import Te6edf3TranslatorHandler
Tff7b72from T7ee787meshchatxT7ee787.T7ee787srcT7ee787.T7ee787backendT7ee787.T7ee787voicemail_manager Tff7b72import Te6edf3VoicemailManager


Tff7b72class T56d364IdentityContextTb4b4b4:
Tff7b72def Tff7b72__init__Tb4b4b4(Tff7b72selfTb4b4b4, Te6edf3identityTb4b4b4: Te6edf3RNSTff7b72.Td2a8ffIdentityTb4b4b4, Te6edf3appTb4b4b4)Tb4b4b4:
Tff7b72selfTff7b72.Td2a8ffidentity Tff7b72= Te6edf3identity
Tff7b72selfTff7b72.Td2a8ffapp Tff7b72= Te6edf3app
Tff7b72selfTff7b72.Td2a8ffidentity_hash Tff7b72= Te6edf3identityTff7b72.Td2a8ffhashTff7b72.Td2a8ffhexTb4b4b4(Tb4b4b4)

T8b949e# Storage paths
Tff7b72selfTff7b72.Td2a8ffstorage_path Tff7b72= Te6edf3osTff7b72.Td2a8ffpathTff7b72.Td2a8ffjoinTb4b4b4(
Te6edf3appTff7b72.Td2a8ffstorage_dirTb4b4b4,
Ta5d6ff"Ta5d6ffidentitiesTa5d6ff"Tb4b4b4,
Tff7b72selfTff7b72.Td2a8ffidentity_hashTb4b4b4,
Tb4b4b4)
Te6edf3osTff7b72.Td2a8ffmakedirsTb4b4b4(Tff7b72selfTff7b72.Td2a8ffstorage_pathTb4b4b4, Te6edf3exist_okTff7b72=Tff7b72TrueTb4b4b4)

Tff7b72selfTff7b72.Td2a8ffdatabase_path Tff7b72= Te6edf3osTff7b72.Td2a8ffpathTff7b72.Td2a8ffjoinTb4b4b4(Tff7b72selfTff7b72.Td2a8ffstorage_pathTb4b4b4, Ta5d6ff"Ta5d6ffdatabase.dbTa5d6ff"Tb4b4b4)
Tff7b72selfTff7b72.Td2a8fflxmf_router_path Tff7b72= Te6edf3osTff7b72.Td2a8ffpathTff7b72.Td2a8ffjoinTb4b4b4(Tff7b72selfTff7b72.Td2a8ffstorage_pathTb4b4b4, Ta5d6ff"Ta5d6fflxmf_routerTa5d6ff"Tb4b4b4)

T8b949e# Identity backup
Te6edf3identity_backup_file Tff7b72= Te6edf3osTff7b72.Td2a8ffpathTff7b72.Td2a8ffjoinTb4b4b4(Tff7b72selfTff7b72.Td2a8ffstorage_pathTb4b4b4, Ta5d6ff"Ta5d6ffidentityTa5d6ff"Tb4b4b4)
Tff7b72if Tff7b72not Te6edf3osTff7b72.Td2a8ffpathTff7b72.Td2a8ffexistsTb4b4b4(Te6edf3identity_backup_fileTb4b4b4)Tb4b4b4:
Te6edf3private_key Tff7b72= Te6edf3identityTff7b72.Td2a8ffget_private_keyTb4b4b4(Tb4b4b4)
Tff7b72if Tff7b72not Te6edf3private_keyTb4b4b4:
Te6edf3msg Tff7b72= Ta5d6ff"Ta5d6ffidentity has no private keyTa5d6ff"
Tff7b72raise Tf85149ValueErrorTb4b4b4(Te6edf3msgTb4b4b4)
Tff7b72with Tffa657openTb4b4b4(Te6edf3identity_backup_fileTb4b4b4, Ta5d6ff"Ta5d6ffwbTa5d6ff"Tb4b4b4) Tff7b72as Te6edf3fTb4b4b4:
Te6edf3fTff7b72.Td2a8ffwriteTb4b4b4(Te6edf3private_keyTb4b4b4)

T8b949e# Session ID for this specific context instance
Tff7b72if Tff7b72not Tffa657hasattrTb4b4b4(Te6edf3appTb4b4b4, Ta5d6ff"Ta5d6ff_identity_session_id_counterTa5d6ff"Tb4b4b4)Tb4b4b4:
Te6edf3appTff7b72.Td2a8ff_identity_session_id_counter Tff7b72= T79c0ff0
Te6edf3appTff7b72.Td2a8ff_identity_session_id_counter Tff7b72+Tff7b72= T79c0ff1
Tff7b72selfTff7b72.Td2a8ffsession_id Tff7b72= Te6edf3appTff7b72.Td2a8ff_identity_session_id_counter

T8b949e# Initialized state
Tff7b72selfTff7b72.Td2a8ffdatabase Tff7b72= Tff7b72None
Tff7b72selfTff7b72.Td2a8ffconfig Tff7b72= Tff7b72None
Tff7b72selfTff7b72.Td2a8ffmessage_handler Tff7b72= Tff7b72None
Tff7b72selfTff7b72.Td2a8ffannounce_manager Tff7b72= Tff7b72None
Tff7b72selfTff7b72.Td2a8ffarchiver_manager Tff7b72= Tff7b72None
Tff7b72selfTff7b72.Td2a8ffmap_manager Tff7b72= Tff7b72None
Tff7b72selfTff7b72.Td2a8ffmap_overlay_manager Tff7b72= Tff7b72None
Tff7b72selfTff7b72.Td2a8ffdocs_manager Tff7b72= Tff7b72None
Tff7b72selfTff7b72.Td2a8ffrepository_server_manager Tff7b72= Tff7b72None
Tff7b72selfTff7b72.Td2a8ffnomadnet_manager Tff7b72= Tff7b72None
Tff7b72selfTff7b72.Td2a8ffmessage_router Tff7b72= Tff7b72None
Tff7b72selfTff7b72.Td2a8fftelephone_manager Tff7b72= Tff7b72None
Tff7b72selfTff7b72.Td2a8ffvoicemail_manager Tff7b72= Tff7b72None
Tff7b72selfTff7b72.Td2a8ffringtone_manager Tff7b72= Tff7b72None
Tff7b72selfTff7b72.Td2a8ffnotification_sound_manager Tff7b72= Tff7b72None
Tff7b72selfTff7b72.Td2a8ffauto_propagation_manager Tff7b72= Tff7b72None
Tff7b72selfTff7b72.Td2a8ffrncp_handler Tff7b72= Tff7b72None
Tff7b72selfTff7b72.Td2a8ffrns_filesync_handler Tff7b72= Tff7b72None
Tff7b72selfTff7b72.Td2a8ffrnsh_manager Tff7b72= Tff7b72None
Tff7b72selfTff7b72.Td2a8ffrnx_manager Tff7b72= Tff7b72None
Tff7b72selfTff7b72.Td2a8ffrnstatus_handler Tff7b72= Tff7b72None
Tff7b72selfTff7b72.Td2a8ffrnpath_handler Tff7b72= Tff7b72None
Tff7b72selfTff7b72.Td2a8ffrnpath_trace_handler Tff7b72= Tff7b72None
Tff7b72selfTff7b72.Td2a8ffrnprobe_handler Tff7b72= Tff7b72None
Tff7b72selfTff7b72.Td2a8fftranslator_handler Tff7b72= Tff7b72None
Tff7b72selfTff7b72.Td2a8ffbot_handler Tff7b72= Tff7b72None
Tff7b72selfTff7b72.Td2a8ffrrc_manager Tff7b72= Tff7b72None
Tff7b72selfTff7b72.Td2a8ffrrc_server_manager Tff7b72= Tff7b72None
Tff7b72selfTff7b72.Td2a8ffforwarding_manager Tff7b72= Tff7b72None
Tff7b72selfTff7b72.Td2a8ffcommunity_interfaces_manager Tff7b72= Tff7b72None
Tff7b72selfTff7b72.Td2a8fflocal_lxmf_destination Tff7b72= Tff7b72None
Tff7b72selfTff7b72.Td2a8ffannounce_handlers Tff7b72= Tb4b4b4[Tb4b4b4]
Tff7b72selfTff7b72.Td2a8ffintegrity_manager Tff7b72= Te6edf3IntegrityManagerTb4b4b4(
Tff7b72selfTff7b72.Td2a8ffstorage_pathTb4b4b4,
Tff7b72selfTff7b72.Td2a8ffdatabase_pathTb4b4b4,
Tff7b72selfTff7b72.Td2a8ffidentity_hashTb4b4b4,
Tb4b4b4)

Tff7b72selfTff7b72.Td2a8ffrunning Tff7b72= Tff7b72False
Tff7b72selfTff7b72.Td2a8ff_deferred_setup_done Tff7b72= Tff7b72False
Tff7b72selfTff7b72.Td2a8ff_deferred_setup_lock Tff7b72= Te6edf3threadingTff7b72.Td2a8ffLockTb4b4b4(Tb4b4b4)
Tff7b72selfTff7b72.Td2a8ff_deferred_setup_in_progress Tff7b72= Tff7b72False
Tff7b72selfTff7b72.Td2a8ff_deferred_setup_finished Tff7b72= Te6edf3threadingTff7b72.Td2a8ffEventTb4b4b4(Tb4b4b4)
Tff7b72selfTff7b72.Td2a8ff_deferred_setup_finishedTff7b72.Td2a8ffsetTb4b4b4(Tb4b4b4)

Tff7b72def Td2a8ff_rrc_name_for_identity_hashTb4b4b4(Tff7b72selfTb4b4b4, Te6edf3identity_hashTb4b4b4)Tb4b4b4:
Tff7b72tryTb4b4b4:
Tff7b72if Tffa657isinstanceTb4b4b4(Te6edf3identity_hashTb4b4b4, Tb4b4b4(Tffa657bytesTb4b4b4, Tffa657bytearrayTb4b4b4)Tb4b4b4)Tb4b4b4:
Te6edf3identity_hash Tff7b72= Tffa657bytesTb4b4b4(Te6edf3identity_hashTb4b4b4)Tff7b72.Td2a8ffhexTb4b4b4(Tb4b4b4)
Tff7b72return Tff7b72selfTff7b72.Td2a8ffappTff7b72.Td2a8ffget_name_for_identity_hashTb4b4b4(Te6edf3identity_hashTb4b4b4)
Tff7b72except Tf85149ExceptionTb4b4b4:
Tff7b72return Tff7b72None

Tff7b72def Td2a8ff_rncp_emit_receive_completedTb4b4b4(Tff7b72selfTb4b4b4, Te6edf3payloadTb4b4b4)Tb4b4b4:
Tff7b72tryTb4b4b4:
Tff7b72from T7ee787meshchatxT7ee787.T7ee787srcT7ee787.T7ee787backendT7ee787.T7ee787async_utils Tff7b72import Te6edf3AsyncUtils

Te6edf3AsyncUtilsTff7b72.Td2a8ffrun_asyncTb4b4b4(
Tff7b72selfTff7b72.Td2a8ffappTff7b72.Td2a8ff_broadcast_websocket_messageTb4b4b4(
Tb4b4b4{Ta5d6ff"Ta5d6fftypeTa5d6ff"Tb4b4b4: Ta5d6ff"Ta5d6ffrncp.receive.completedTa5d6ff"Tb4b4b4, Tff7b72*Tff7b72*Te6edf3payloadTb4b4b4}Tb4b4b4,
Tb4b4b4)Tb4b4b4,
Tb4b4b4)
Tff7b72except Tf85149ExceptionTb4b4b4:
Tff7b72pass

Tff7b72def Td2a8ff_filesync_emitTb4b4b4(Tff7b72selfTb4b4b4, Te6edf3messageTb4b4b4)Tb4b4b4:
Tff7b72tryTb4b4b4:
Tff7b72from T7ee787meshchatxT7ee787.T7ee787srcT7ee787.T7ee787backendT7ee787.T7ee787async_utils Tff7b72import Te6edf3AsyncUtils

Te6edf3AsyncUtilsTff7b72.Td2a8ffrun_asyncTb4b4b4(Tff7b72selfTff7b72.Td2a8ffappTff7b72.Td2a8ff_broadcast_websocket_messageTb4b4b4(Te6edf3messageTb4b4b4)Tb4b4b4)
Tff7b72except Tf85149ExceptionTb4b4b4:
Tff7b72pass

Tff7b72def Td2a8ffsetupTb4b4b4(Tff7b72selfTb4b4b4)Tb4b4b4:
T8b949e"""Initialize core messaging identity state.

Secondary tools (RN*, bots, RRC connect, docs populate, map overlays)
are started by setup_deferred_services() after network_ready so the UI
and LXMF path become available sooner.
"""
Tffa657printTb4b4b4(Ta5d6fffTa5d6ff"Ta5d6ffSetting up Identity Context for Tffd700{Tff7b72selfTff7b72.Td2a8ffidentity_hashTffd700}Ta5d6ff...Ta5d6ff"Tb4b4b4)

T8b949e# 0. Clear any previous integrity and database health issues on the app
Tff7b72selfTff7b72.Td2a8ffappTff7b72.Td2a8ffintegrity_issues Tff7b72= Tb4b4b4[Tb4b4b4]
Tff7b72selfTff7b72.Td2a8ffappTff7b72.Td2a8ffdatabase_health_issues Tff7b72= Tb4b4b4[Tb4b4b4]
Tff7b72selfTff7b72.Td2a8ff_deferred_setup_done Tff7b72= Tff7b72False
Tff7b72selfTff7b72.Td2a8ff_deferred_setup_in_progress Tff7b72= Tff7b72False
Tff7b72selfTff7b72.Td2a8ff_deferred_setup_finishedTff7b72.Td2a8ffsetTb4b4b4(Tb4b4b4)

T8b949e# 1. Cleanup RNS state for this identity if any lingers
Tff7b72selfTff7b72.Td2a8ffappTff7b72.Td2a8ffcleanup_rns_state_for_identityTb4b4b4(Tff7b72selfTff7b72.Td2a8ffidentityTff7b72.Td2a8ffhashTb4b4b4)

T8b949e# 2. Initialize Database
Tff7b72if Tffa657getattrTb4b4b4(Tff7b72selfTff7b72.Td2a8ffappTb4b4b4, Ta5d6ff"Ta5d6ffemergencyTa5d6ff"Tb4b4b4, Tff7b72FalseTb4b4b4)Tb4b4b4:
Tffa657printTb4b4b4(Ta5d6ff"Ta5d6ffEMERGENCY MODE ENABLED: Using in-memory database.Ta5d6ff"Tb4b4b4)
Tff7b72selfTff7b72.Td2a8ffdatabase Tff7b72= Te6edf3DatabaseTb4b4b4(Ta5d6ff"Ta5d6ff:memory:Ta5d6ff"Tb4b4b4)
Tff7b72elseTb4b4b4:
Tff7b72selfTff7b72.Td2a8ffdatabase Tff7b72= Te6edf3DatabaseTb4b4b4(Tff7b72selfTff7b72.Td2a8ffdatabase_pathTb4b4b4)

T8b949e# Critical integrity only at boot (full walk deferred)
Tff7b72if Tff7b72not Tffa657getattrTb4b4b4(Tff7b72selfTff7b72.Td2a8ffappTb4b4b4, Ta5d6ff"Ta5d6ffemergencyTa5d6ff"Tb4b4b4, Tff7b72FalseTb4b4b4)Tb4b4b4:
Te6edf3is_okTb4b4b4, Te6edf3issues Tff7b72= Tff7b72selfTff7b72.Td2a8ffintegrity_managerTff7b72.Td2a8ffcheck_integrityTb4b4b4(Te6edf3critical_onlyTff7b72=Tff7b72TrueTb4b4b4)
Tff7b72if Tff7b72not Te6edf3is_okTb4b4b4:
Tffa657printTb4b4b4(
Ta5d6fffTa5d6ff"Ta5d6ffINTEGRITY WARNING for Tffd700{Tff7b72selfTff7b72.Td2a8ffidentity_hashTffd700}Ta5d6ff: Tffd700{Ta5d6ff'Ta5d6ff, Ta5d6ff'Tff7b72.Td2a8ffjoinTb4b4b4(Te6edf3issuesTb4b4b4)Tffd700}Ta5d6ff"Tb4b4b4,
Tb4b4b4)
Tff7b72if Tff7b72not Tffa657hasattrTb4b4b4(Tff7b72selfTff7b72.Td2a8ffappTb4b4b4, Ta5d6ff"Ta5d6ffintegrity_issuesTa5d6ff"Tb4b4b4)Tb4b4b4:
Tff7b72selfTff7b72.Td2a8ffappTff7b72.Td2a8ffintegrity_issues Tff7b72= Tb4b4b4[Tb4b4b4]
Tff7b72selfTff7b72.Td2a8ffappTff7b72.Td2a8ffintegrity_issuesTff7b72.Td2a8ffextendTb4b4b4(Te6edf3issuesTb4b4b4)
Te6edf3critical Tff7b72= Te6edf3select_critical_integrity_issuesTb4b4b4(Te6edf3issuesTb4b4b4)
Tff7b72if Te6edf3criticalTb4b4b4:
Tff7b72raise Te6edf3CriticalIntegrityErrorTb4b4b4(
Ta5d6ff"Ta5d6ffCritical integrity failure: Ta5d6ff" Tff7b72+ Ta5d6ff"Ta5d6ff; Ta5d6ff"Tff7b72.Td2a8ffjoinTb4b4b4(Te6edf3criticalTb4b4b4)Tb4b4b4,
Tb4b4b4)

Tff7b72tryTb4b4b4:
Tff7b72selfTff7b72.Td2a8ffdatabaseTff7b72.Td2a8ffinitializeTb4b4b4(Tb4b4b4)
Tff7b72selfTff7b72.Td2a8ffdatabaseTff7b72.Td2a8ff_tune_sqlite_pragmasTb4b4b4(Tb4b4b4)
Tff7b72except Tf85149Exception Tff7b72as Te6edf3excTb4b4b4:
Tff7b72if Tff7b72not Tff7b72selfTff7b72.Td2a8ffappTff7b72.Td2a8ffauto_recover Tff7b72and Tff7b72not Tffa657getattrTb4b4b4(Tff7b72selfTff7b72.Td2a8ffappTb4b4b4, Ta5d6ff"Ta5d6ffemergencyTa5d6ff"Tb4b4b4, Tff7b72FalseTb4b4b4)Tb4b4b4:
Tff7b72raise
Tffa657printTb4b4b4(
Ta5d6fffTa5d6ff"Ta5d6ffDatabase initialization failed for Tffd700{Tff7b72selfTff7b72.Td2a8ffidentity_hashTffd700}Ta5d6ff, attempting recovery: Tffd700{Te6edf3excTffd700}Ta5d6ff"Tb4b4b4,
Tb4b4b4)
Tff7b72if Tff7b72not Tffa657getattrTb4b4b4(Tff7b72selfTff7b72.Td2a8ffappTb4b4b4, Ta5d6ff"Ta5d6ffemergencyTa5d6ff"Tb4b4b4, Tff7b72FalseTb4b4b4)Tb4b4b4:
Tff7b72selfTff7b72.Td2a8ffappTff7b72.Td2a8ff_run_startup_auto_recoveryTb4b4b4(Tb4b4b4)
Tff7b72selfTff7b72.Td2a8ffdatabaseTff7b72.Td2a8ffinitializeTb4b4b4(Tb4b4b4)
Tff7b72selfTff7b72.Td2a8ffdatabaseTff7b72.Td2a8ff_tune_sqlite_pragmasTb4b4b4(Tb4b4b4)

T8b949e# 3. Initialize Config and core managers
Tff7b72selfTff7b72.Td2a8ffconfig Tff7b72= Te6edf3ConfigManagerTb4b4b4(Tff7b72selfTff7b72.Td2a8ffdatabaseTb4b4b4)

Tff7b72if Tb4b4b4(
Tffa657hasattrTb4b4b4(Tff7b72selfTff7b72.Td2a8ffappTb4b4b4, Ta5d6ff"Ta5d6ffgitea_base_url_overrideTa5d6ff"Tb4b4b4)
Tff7b72and Tff7b72selfTff7b72.Td2a8ffappTff7b72.Td2a8ffgitea_base_url_override
Tb4b4b4)Tb4b4b4:
Tff7b72selfTff7b72.Td2a8ffconfigTff7b72.Td2a8ffgitea_base_urlTff7b72.Td2a8ffsetTb4b4b4(Tff7b72selfTff7b72.Td2a8ffappTff7b72.Td2a8ffgitea_base_url_overrideTb4b4b4)

Tff7b72selfTff7b72.Td2a8ffmessage_handler Tff7b72= Te6edf3MessageHandlerTb4b4b4(Tff7b72selfTff7b72.Td2a8ffdatabaseTb4b4b4)
Tff7b72selfTff7b72.Td2a8ffannounce_manager Tff7b72= Te6edf3AnnounceManagerTb4b4b4(Tff7b72selfTff7b72.Td2a8ffdatabaseTb4b4b4, Tff7b72selfTff7b72.Td2a8ffconfigTb4b4b4)
Tff7b72selfTff7b72.Td2a8ffarchiver_manager Tff7b72= Te6edf3ArchiverManagerTb4b4b4(Tff7b72selfTff7b72.Td2a8ffdatabaseTb4b4b4)
Tff7b72selfTff7b72.Td2a8ffmap_manager Tff7b72= Te6edf3MapManagerTb4b4b4(Tff7b72selfTff7b72.Td2a8ffconfigTb4b4b4, Tff7b72selfTff7b72.Td2a8ffappTff7b72.Td2a8ffstorage_dirTb4b4b4)
Tff7b72selfTff7b72.Td2a8ffmap_overlay_manager Tff7b72= Tff7b72None
Tff7b72selfTff7b72.Td2a8ffdocs_manager Tff7b72= Te6edf3DocsManagerTb4b4b4(
Tff7b72selfTff7b72.Td2a8ffconfigTb4b4b4,
Tff7b72selfTff7b72.Td2a8ffappTff7b72.Td2a8ffget_public_pathTb4b4b4(Tb4b4b4)Tb4b4b4,
Te6edf3project_rootTff7b72=Te6edf3osTff7b72.Td2a8ffpathTff7b72.Td2a8ffdirnameTb4b4b4(
Te6edf3osTff7b72.Td2a8ffpathTff7b72.Td2a8ffdirnameTb4b4b4(
Te6edf3osTff7b72.Td2a8ffpathTff7b72.Td2a8ffdirnameTb4b4b4(Te6edf3osTff7b72.Td2a8ffpathTff7b72.Td2a8ffdirnameTb4b4b4(Te6edf3osTff7b72.Td2a8ffpathTff7b72.Td2a8ffabspathTb4b4b4(Tff7b72__file__Tb4b4b4)Tb4b4b4)Tb4b4b4)Tb4b4b4,
Tb4b4b4)Tb4b4b4,
Tb4b4b4)Tb4b4b4,
Te6edf3storage_dirTff7b72=Tff7b72selfTff7b72.Td2a8ffstorage_pathTb4b4b4,
Te6edf3populateTff7b72=Tff7b72FalseTb4b4b4,
Tb4b4b4)
Tff7b72selfTff7b72.Td2a8ffrepository_server_manager Tff7b72= Te6edf3RepositoryServerManagerTb4b4b4(
Tff7b72selfTff7b72.Td2a8ffstorage_pathTb4b4b4,
Te6edf3public_dirTff7b72=Tff7b72selfTff7b72.Td2a8ffappTff7b72.Td2a8ffget_public_pathTb4b4b4(Tb4b4b4)Tb4b4b4,
Tb4b4b4)
Tff7b72selfTff7b72.Td2a8ffnomadnet_manager Tff7b72= Te6edf3NomadNetworkManagerTb4b4b4(
Tff7b72selfTff7b72.Td2a8ffconfigTb4b4b4,
Tff7b72selfTff7b72.Td2a8ffarchiver_managerTb4b4b4,
Tff7b72selfTff7b72.Td2a8ffdatabaseTb4b4b4,
Tb4b4b4)

Tff7b72selfTff7b72.Td2a8ffdatabaseTff7b72.Td2a8ffmessagesTff7b72.Td2a8ffmark_stuck_messages_as_failedTb4b4b4(Tb4b4b4)

Tff7b72if Tff7b72not Tffa657getattrTb4b4b4(Tff7b72selfTff7b72.Td2a8ffappTb4b4b4, Ta5d6ff"Ta5d6ffemergencyTa5d6ff"Tb4b4b4, Tff7b72FalseTb4b4b4)Tb4b4b4:
Te6edf3db_issues Tff7b72= Tff7b72selfTff7b72.Td2a8ffdatabaseTff7b72.Td2a8ffcheck_db_health_at_openTb4b4b4(
Tff7b72selfTff7b72.Td2a8ffstorage_pathTb4b4b4,
Te6edf3quickTff7b72=Tff7b72TrueTb4b4b4,
Tb4b4b4)
Tff7b72if Te6edf3db_issuesTb4b4b4:
Tff7b72selfTff7b72.Td2a8ffappTff7b72.Td2a8ffdatabase_health_issues Tff7b72= Te6edf3db_issues
Tffa657printTb4b4b4(
Ta5d6fffTa5d6ff"Ta5d6ffDatabase health check for Tffd700{Tff7b72selfTff7b72.Td2a8ffidentity_hashTffd700}Ta5d6ff: Tffd700{Ta5d6ff'Ta5d6ff, Ta5d6ff'Tff7b72.Td2a8ffjoinTb4b4b4(Te6edf3db_issuesTb4b4b4)Tffd700}Ta5d6ff"Tb4b4b4,
Tb4b4b4)

T8b949e# 4. Initialize LXMF Router
Te6edf3propagation_stamp_cost Tff7b72= Tff7b72selfTff7b72.Td2a8ffconfigTff7b72.Td2a8fflxmf_propagation_node_stamp_costTff7b72.Td2a8ffgetTb4b4b4(Tb4b4b4)
Te6edf3max_inbound_syncs Tff7b72= Tff7b72selfTff7b72.Td2a8ffconfigTff7b72.Td2a8fflxmf_propagation_max_inbound_syncsTff7b72.Td2a8ffgetTb4b4b4(Tb4b4b4)
Tff7b72if Tff7b72not Tffa657isinstanceTb4b4b4(Te6edf3max_inbound_syncsTb4b4b4, Tffa657intTb4b4b4) Tff7b72or Te6edf3max_inbound_syncs Tff7b72< T79c0ff1Tb4b4b4:
Te6edf3max_inbound_syncs Tff7b72= T79c0ff3
Te6edf3sequential_validation Tff7b72= Tffa657boolTb4b4b4(
Tff7b72selfTff7b72.Td2a8ffconfigTff7b72.Td2a8fflxmf_propagation_sequential_validationTff7b72.Td2a8ffgetTb4b4b4(Tb4b4b4)Tb4b4b4,
Tb4b4b4)
Te6edf3static_sequential Tff7b72= Tff7b72not Tffa657boolTb4b4b4(
Tff7b72selfTff7b72.Td2a8ffconfigTff7b72.Td2a8fflxmf_propagation_static_peers_bypass_sequentialTff7b72.Td2a8ffgetTb4b4b4(Tb4b4b4)Tb4b4b4,
Tb4b4b4)
Tff7b72selfTff7b72.Td2a8ffmessage_router Tff7b72= Te6edf3create_lxmf_routerTb4b4b4(
Te6edf3identityTff7b72=Tff7b72selfTff7b72.Td2a8ffidentityTb4b4b4,
Te6edf3storagepathTff7b72=Tff7b72selfTff7b72.Td2a8fflxmf_router_pathTb4b4b4,
Te6edf3propagation_costTff7b72=Te6edf3propagation_stamp_costTb4b4b4,
Te6edf3max_inbound_syncsTff7b72=Te6edf3max_inbound_syncsTb4b4b4,
Te6edf3sequential_validationTff7b72=Te6edf3sequential_validationTb4b4b4,
Te6edf3static_sequentialTff7b72=Te6edf3static_sequentialTb4b4b4,
Tb4b4b4)
Tff7b72selfTff7b72.Td2a8ffmessage_routerTff7b72.Td2a8ffPROCESSING_INTERVAL Tff7b72= T79c0ff1
Tff7b72selfTff7b72.Td2a8ffmessage_routerTff7b72.Td2a8ffdelivery_per_transfer_limit Tff7b72= Tb4b4b4(
Tff7b72selfTff7b72.Td2a8ffconfigTff7b72.Td2a8fflxmf_delivery_transfer_limit_in_bytesTff7b72.Td2a8ffgetTb4b4b4(Tb4b4b4) Tff7b72/ T79c0ff1000
Tb4b4b4)
Tff7b72selfTff7b72.Td2a8ffmessage_routerTff7b72.Td2a8ffpropagation_per_transfer_limit Tff7b72= Tb4b4b4(
Tff7b72selfTff7b72.Td2a8ffconfigTff7b72.Td2a8fflxmf_propagation_transfer_limit_in_bytesTff7b72.Td2a8ffgetTb4b4b4(Tb4b4b4) Tff7b72/ T79c0ff1000
Tb4b4b4)
Tff7b72selfTff7b72.Td2a8ffmessage_routerTff7b72.Td2a8ffpropagation_per_sync_limit Tff7b72= Tb4b4b4(
Tff7b72selfTff7b72.Td2a8ffconfigTff7b72.Td2a8fflxmf_propagation_sync_limit_in_bytesTff7b72.Td2a8ffgetTb4b4b4(Tb4b4b4) Tff7b72/ T79c0ff1000
Tb4b4b4)

Te6edf3inbound_stamp_cost Tff7b72= Tff7b72selfTff7b72.Td2a8ffconfigTff7b72.Td2a8fflxmf_inbound_stamp_costTff7b72.Td2a8ffgetTb4b4b4(Tb4b4b4)
Tff7b72if Tb4b4b4(
Tff7b72selfTff7b72.Td2a8ffconfigTff7b72.Td2a8ffblock_all_from_strangersTff7b72.Td2a8ffgetTb4b4b4(Tb4b4b4)
Tff7b72and Tffa657isinstanceTb4b4b4(Te6edf3inbound_stamp_costTb4b4b4, Tffa657intTb4b4b4)
Tff7b72and Te6edf3inbound_stamp_cost Tff7b72< T79c0ff254
Tb4b4b4)Tb4b4b4:
Te6edf3inbound_stamp_cost Tff7b72= T79c0ff254
Tff7b72selfTff7b72.Td2a8ffconfigTff7b72.Td2a8fflxmf_inbound_stamp_costTff7b72.Td2a8ffsetTb4b4b4(T79c0ff254Tb4b4b4)
Tff7b72selfTff7b72.Td2a8fflocal_lxmf_destination Tff7b72= Tff7b72selfTff7b72.Td2a8ffmessage_routerTff7b72.Td2a8ffregister_delivery_identityTb4b4b4(
Te6edf3identityTff7b72=Tff7b72selfTff7b72.Td2a8ffidentityTb4b4b4,
Te6edf3display_nameTff7b72=Tff7b72selfTff7b72.Td2a8ffconfigTff7b72.Td2a8ffdisplay_nameTff7b72.Td2a8ffgetTb4b4b4(Tb4b4b4)Tb4b4b4,
Te6edf3stamp_costTff7b72=Te6edf3inbound_stamp_costTb4b4b4,
Tb4b4b4)
T8b949e# Announce stamp cost alone does not drop invalid stamps. Enforce when
T8b949e# a non-zero inbound cost is configured so flood/inbound controls work.
Tff7b72if Tffa657isinstanceTb4b4b4(Te6edf3inbound_stamp_costTb4b4b4, Tffa657intTb4b4b4) Tff7b72and Te6edf3inbound_stamp_cost Tff7b72> T79c0ff0Tb4b4b4:
Tff7b72selfTff7b72.Td2a8ffmessage_routerTff7b72.Td2a8ffenforce_stampsTb4b4b4(Tb4b4b4)
Tff7b72elif Tffa657hasattrTb4b4b4(Tff7b72selfTff7b72.Td2a8ffmessage_routerTb4b4b4, Ta5d6ff"Ta5d6ffignore_stampsTa5d6ff"Tb4b4b4)Tb4b4b4:
Tff7b72selfTff7b72.Td2a8ffmessage_routerTff7b72.Td2a8ffignore_stampsTb4b4b4(Tb4b4b4)

Tff7b72selfTff7b72.Td2a8ffforwarding_manager Tff7b72= Te6edf3ForwardingManagerTb4b4b4(
Tff7b72selfTff7b72.Td2a8ffdatabaseTb4b4b4,
Tff7b72selfTff7b72.Td2a8fflxmf_router_pathTb4b4b4,
Tff7b72lambda Te6edf3msgTb4b4b4: Tff7b72selfTff7b72.Td2a8ffappTff7b72.Td2a8ffon_lxmf_deliveryTb4b4b4(Te6edf3msgTb4b4b4, Te6edf3contextTff7b72=Tff7b72selfTb4b4b4)Tb4b4b4,
Te6edf3configTff7b72=Tff7b72selfTff7b72.Td2a8ffconfigTb4b4b4,
Tb4b4b4)
Tff7b72selfTff7b72.Td2a8ffforwarding_managerTff7b72.Td2a8ffload_aliasesTb4b4b4(Tb4b4b4)

Tff7b72selfTff7b72.Td2a8ffmessage_routerTff7b72.Td2a8ffregister_delivery_callbackTb4b4b4(
Tff7b72lambda Te6edf3msgTb4b4b4: Tff7b72selfTff7b72.Td2a8ffappTff7b72.Td2a8ffon_lxmf_deliveryTb4b4b4(Te6edf3msgTb4b4b4, Te6edf3contextTff7b72=Tff7b72selfTb4b4b4)Tb4b4b4,
Tb4b4b4)

Tff7b72with Te6edf3contextlibTff7b72.Td2a8ffsuppressTb4b4b4(Tf85149ExceptionTb4b4b4)Tb4b4b4:
Te6edf3preferred_node Tff7b72= Tb4b4b4(
Tff7b72selfTff7b72.Td2a8ffconfigTff7b72.Td2a8fflxmf_preferred_propagation_node_destination_hashTff7b72.Td2a8ffgetTb4b4b4(Tb4b4b4)
Tb4b4b4)
Tff7b72if Te6edf3preferred_nodeTb4b4b4:
Tff7b72selfTff7b72.Td2a8ffappTff7b72.Td2a8ffset_active_propagation_nodeTb4b4b4(Te6edf3preferred_nodeTb4b4b4, Te6edf3contextTff7b72=Tff7b72selfTb4b4b4)

Tff7b72with Te6edf3contextlibTff7b72.Td2a8ffsuppressTb4b4b4(Tf85149ExceptionTb4b4b4)Tb4b4b4:
Tff7b72if Tff7b72selfTff7b72.Td2a8ffconfigTff7b72.Td2a8fflxmf_local_propagation_node_enabledTff7b72.Td2a8ffgetTb4b4b4(Tb4b4b4)Tb4b4b4:
Tff7b72selfTff7b72.Td2a8ffappTff7b72.Td2a8ffenable_local_propagation_nodeTb4b4b4(Tff7b72TrueTb4b4b4, Te6edf3contextTff7b72=Tff7b72selfTb4b4b4)

T8b949e# Telephone is part of core UX (calls overlay).

Te6edf3identity Tff7b72= Tff7b72selfTff7b72.Td2a8ffidentity
Tff7b72if Te6edf3identity Tff7b72is Tff7b72NoneTb4b4b4:
Te6edf3msg Tff7b72= Ta5d6ff"Ta5d6ffidentity is required for manager setupTa5d6ff"
Tff7b72raise Tf85149RuntimeErrorTb4b4b4(Te6edf3msgTb4b4b4)
Tff7b72selfTff7b72.Td2a8fftelephone_manager Tff7b72= Te6edf3TelephoneManagerTb4b4b4(
Te6edf3identityTb4b4b4,
Te6edf3config_managerTff7b72=Tff7b72selfTff7b72.Td2a8ffconfigTb4b4b4,
Te6edf3storage_dirTff7b72=Tff7b72selfTff7b72.Td2a8ffstorage_pathTb4b4b4,
Te6edf3dbTff7b72=Tff7b72selfTff7b72.Td2a8ffdatabaseTb4b4b4,
Tb4b4b4)
Tff7b72selfTff7b72.Td2a8fftelephone_managerTff7b72.Td2a8ffweb_audio_required Tff7b72= Tffa657boolTb4b4b4(
Tffa657getattrTb4b4b4(Tff7b72selfTff7b72.Td2a8ffappTb4b4b4, Ta5d6ff"Ta5d6ffweb_audio_requiredTa5d6ff"Tb4b4b4, Tff7b72lambdaTb4b4b4: Tff7b72FalseTb4b4b4)Tb4b4b4(Tb4b4b4)Tb4b4b4,
Tb4b4b4)
Tff7b72selfTff7b72.Td2a8fftelephone_managerTff7b72.Td2a8ffget_name_for_identity_hash Tff7b72= Tb4b4b4(
Tff7b72selfTff7b72.Td2a8ffappTff7b72.Td2a8ffget_name_for_identity_hash
Tb4b4b4)
Tff7b72selfTff7b72.Td2a8fftelephone_managerTff7b72.Td2a8ffon_initiation_status_callback Tff7b72= Tff7b72lambda Te6edf3statusTb4b4b4, Te6edf3targetTb4b4b4: Tb4b4b4(
Tff7b72selfTff7b72.Td2a8ffappTff7b72.Td2a8ffon_telephone_initiation_statusTb4b4b4(
Te6edf3statusTb4b4b4,
Te6edf3targetTb4b4b4,
Te6edf3contextTff7b72=Tff7b72selfTb4b4b4,
Tb4b4b4)
Tb4b4b4)
Tff7b72selfTff7b72.Td2a8fftelephone_managerTff7b72.Td2a8ffregister_ringing_callbackTb4b4b4(
Tff7b72lambda Te6edf3callTb4b4b4: Tff7b72selfTff7b72.Td2a8ffappTff7b72.Td2a8ffon_incoming_telephone_callTb4b4b4(Te6edf3callTb4b4b4, Te6edf3contextTff7b72=Tff7b72selfTb4b4b4)Tb4b4b4,
Tb4b4b4)
Tff7b72selfTff7b72.Td2a8fftelephone_managerTff7b72.Td2a8ffregister_established_callbackTb4b4b4(
Tff7b72lambda Te6edf3callTb4b4b4: Tff7b72selfTff7b72.Td2a8ffappTff7b72.Td2a8ffon_telephone_call_establishedTb4b4b4(Te6edf3callTb4b4b4, Te6edf3contextTff7b72=Tff7b72selfTb4b4b4)Tb4b4b4,
Tb4b4b4)
Tff7b72selfTff7b72.Td2a8fftelephone_managerTff7b72.Td2a8ffregister_ended_callbackTb4b4b4(
Tff7b72lambda Te6edf3callTb4b4b4: Tff7b72selfTff7b72.Td2a8ffappTff7b72.Td2a8ffon_telephone_call_endedTb4b4b4(Te6edf3callTb4b4b4, Te6edf3contextTff7b72=Tff7b72selfTb4b4b4)Tb4b4b4,
Tb4b4b4)

Tff7b72if Tff7b72not Tffa657getattrTb4b4b4(Tff7b72selfTff7b72.Td2a8ffappTb4b4b4, Ta5d6ff"Ta5d6ffemergencyTa5d6ff"Tb4b4b4, Tff7b72FalseTb4b4b4)Tb4b4b4:
T8b949e# Telephony must not take down mesh startup. Android may ship an
T8b949e# older LXST without duplex helpers, and audio backends can fail
T8b949e# while LXMF/RNS remain usable.
Tff7b72tryTb4b4b4:
Tff7b72selfTff7b72.Td2a8fftelephone_managerTff7b72.Td2a8ffinit_telephoneTb4b4b4(Tb4b4b4)
Tff7b72with Te6edf3contextlibTff7b72.Td2a8ffsuppressTb4b4b4(Tf85149ExceptionTb4b4b4)Tb4b4b4:
Tff7b72selfTff7b72.Td2a8ffappTff7b72.Td2a8ffsync_telephone_call_policyTb4b4b4(Te6edf3contextTff7b72=Tff7b72selfTb4b4b4)
Tff7b72except Tf85149Exception Tff7b72as Te6edf3excTb4b4b4:
Tffa657printTb4b4b4(Ta5d6fffTa5d6ff"Ta5d6ffTelephone init failed (mesh continues): Tffd700{Te6edf3excTffd700}Ta5d6ff"Tb4b4b4, Te6edf3flushTff7b72=Tff7b72TrueTb4b4b4)

Tff7b72selfTff7b72.Td2a8ffvoicemail_manager Tff7b72= Te6edf3VoicemailManagerTb4b4b4(
Te6edf3dbTff7b72=Tff7b72selfTff7b72.Td2a8ffdatabaseTb4b4b4,
Te6edf3configTff7b72=Tff7b72selfTff7b72.Td2a8ffconfigTb4b4b4,
Te6edf3telephone_managerTff7b72=Tff7b72selfTff7b72.Td2a8fftelephone_managerTb4b4b4,
Te6edf3storage_dirTff7b72=Tff7b72selfTff7b72.Td2a8ffstorage_pathTb4b4b4,
Tb4b4b4)
Tff7b72selfTff7b72.Td2a8ffvoicemail_managerTff7b72.Td2a8ffget_name_for_identity_hash Tff7b72= Tb4b4b4(
Tff7b72selfTff7b72.Td2a8ffappTff7b72.Td2a8ffget_name_for_identity_hash
Tb4b4b4)
Tff7b72selfTff7b72.Td2a8ffvoicemail_managerTff7b72.Td2a8ffon_new_voicemail_callback Tff7b72= Tff7b72lambda Te6edf3vmTb4b4b4: Tb4b4b4(
Tff7b72selfTff7b72.Td2a8ffappTff7b72.Td2a8ffon_new_voicemail_receivedTb4b4b4(Te6edf3vmTb4b4b4, Te6edf3contextTff7b72=Tff7b72selfTb4b4b4)
Tb4b4b4)

Tff7b72selfTff7b72.Td2a8ffringtone_manager Tff7b72= Te6edf3RingtoneManagerTb4b4b4(
Te6edf3configTff7b72=Tff7b72selfTff7b72.Td2a8ffconfigTb4b4b4,
Te6edf3storage_dirTff7b72=Tff7b72selfTff7b72.Td2a8ffstorage_pathTb4b4b4,
Tb4b4b4)

Tff7b72selfTff7b72.Td2a8ffnotification_sound_manager Tff7b72= Te6edf3RingtoneManagerTb4b4b4(
Te6edf3configTff7b72=Tff7b72selfTff7b72.Td2a8ffconfigTb4b4b4,
Te6edf3storage_dirTff7b72=Tff7b72selfTff7b72.Td2a8ffstorage_pathTb4b4b4,
Te6edf3asset_subdirTff7b72=Ta5d6ff"Ta5d6ffnotification_soundsTa5d6ff"Tb4b4b4,
Te6edf3filename_prefixTff7b72=Ta5d6ff"Ta5d6ffnotificationTa5d6ff"Tb4b4b4,
Tb4b4b4)

Tff7b72selfTff7b72.Td2a8ffcommunity_interfaces_manager Tff7b72= Te6edf3CommunityInterfacesManagerTb4b4b4(
Te6edf3public_override_pathTff7b72=Tff7b72selfTff7b72.Td2a8ffappTff7b72.Td2a8ffget_public_pathTb4b4b4(Ta5d6ff"Ta5d6ffcommunity_interfaces.jsonTa5d6ff"Tb4b4b4)Tb4b4b4,
Te6edf3cache_pathTff7b72=Te6edf3osTff7b72.Td2a8ffpathTff7b72.Td2a8ffjoinTb4b4b4(
Tff7b72selfTff7b72.Td2a8ffstorage_pathTb4b4b4,
Ta5d6ff"Ta5d6ffcommunity_interfaces_cache.jsonTa5d6ff"Tb4b4b4,
Tb4b4b4)Tb4b4b4,
Tb4b4b4)

Tff7b72selfTff7b72.Td2a8ffauto_propagation_manager Tff7b72= Te6edf3AutoPropagationManagerTb4b4b4(
Te6edf3appTff7b72=Tff7b72selfTff7b72.Td2a8ffappTb4b4b4,
Te6edf3contextTff7b72=Tff7b72selfTb4b4b4,
Tb4b4b4)

T8b949e# Tool handlers stay None until deferred setup finishes.
Tff7b72selfTff7b72.Td2a8ffrncp_handler Tff7b72= Tff7b72None
Tff7b72selfTff7b72.Td2a8ffrns_filesync_handler Tff7b72= Tff7b72None
Tff7b72selfTff7b72.Td2a8ffrnsh_manager Tff7b72= Tff7b72None
Tff7b72selfTff7b72.Td2a8ffrnx_manager Tff7b72= Tff7b72None
Tff7b72selfTff7b72.Td2a8ffrnstatus_handler Tff7b72= Tff7b72None
Tff7b72selfTff7b72.Td2a8ffrnpath_handler Tff7b72= Tff7b72None
Tff7b72selfTff7b72.Td2a8ffrnpath_trace_handler Tff7b72= Tff7b72None
Tff7b72selfTff7b72.Td2a8ffrnprobe_handler Tff7b72= Tff7b72None
Tff7b72selfTff7b72.Td2a8fftranslator_handler Tff7b72= Tff7b72None
Tff7b72selfTff7b72.Td2a8ffbot_handler Tff7b72= Tff7b72None
Tff7b72selfTff7b72.Td2a8ffrrc_manager Tff7b72= Tff7b72None
Tff7b72selfTff7b72.Td2a8ffrrc_server_manager Tff7b72= Tff7b72None

Tff7b72selfTff7b72.Td2a8ffregister_announce_handlersTb4b4b4(Tb4b4b4)

Tff7b72selfTff7b72.Td2a8ffrunning Tff7b72= Tff7b72True
Tff7b72selfTff7b72.Td2a8ffstart_background_threadsTb4b4b4(Tb4b4b4)

Tffa657printTb4b4b4(Ta5d6fffTa5d6ff"Ta5d6ffIdentity Context for Tffd700{Tff7b72selfTff7b72.Td2a8ffidentity_hashTffd700}Ta5d6ff core is now running.Ta5d6ff"Tb4b4b4)

Tff7b72def Td2a8ffsetup_deferred_servicesTb4b4b4(Tff7b72selfTb4b4b4)Tb4b4b4:
T8b949e"""Finish non-critical managers after network_ready.

Idempotent and teardown-safe: concurrent callers share one run, and
teardown waits for an in-flight run so handlers are not resurrected
after the context is stopped.
"""
Tff7b72if Tff7b72not Tff7b72selfTff7b72.Td2a8ffrunningTb4b4b4:
Tff7b72return
Tff7b72with Tff7b72selfTff7b72.Td2a8ff_deferred_setup_lockTb4b4b4:
Tff7b72if Tff7b72selfTff7b72.Td2a8ff_deferred_setup_done Tff7b72or Tff7b72selfTff7b72.Td2a8ff_deferred_setup_in_progressTb4b4b4:
Tff7b72return
Tff7b72if Tff7b72not Tff7b72selfTff7b72.Td2a8ffrunningTb4b4b4:
Tff7b72return
Tff7b72selfTff7b72.Td2a8ff_deferred_setup_in_progress Tff7b72= Tff7b72True
Tff7b72selfTff7b72.Td2a8ff_deferred_setup_finishedTff7b72.Td2a8ffclearTb4b4b4(Tb4b4b4)

Tff7b72tryTb4b4b4:
Tff7b72if Tff7b72not Tff7b72selfTff7b72.Td2a8ffrunningTb4b4b4:
Tff7b72return
Tffa657printTb4b4b4(Ta5d6fffTa5d6ff"Ta5d6ffDeferred setup for Identity Context Tffd700{Tff7b72selfTff7b72.Td2a8ffidentity_hashTffd700}Ta5d6ff...Ta5d6ff"Tb4b4b4)
Tff7b72selfTff7b72.Td2a8ff_run_deferred_services_bodyTb4b4b4(Tb4b4b4)
Tff7b72if Tff7b72selfTff7b72.Td2a8ffrunningTb4b4b4:
Tff7b72with Tff7b72selfTff7b72.Td2a8ff_deferred_setup_lockTb4b4b4:
Tff7b72selfTff7b72.Td2a8ff_deferred_setup_done Tff7b72= Tff7b72True
Tffa657printTb4b4b4(
Ta5d6fffTa5d6ff"Ta5d6ffIdentity Context for Tffd700{Tff7b72selfTff7b72.Td2a8ffidentity_hashTffd700}Ta5d6ff deferred setup complete.Ta5d6ff"Tb4b4b4,
Tb4b4b4)
Tff7b72elseTb4b4b4:
Tffa657printTb4b4b4(
Ta5d6fffTa5d6ff"Ta5d6ffDeferred setup aborted for torn-down identity Tffd700{Tff7b72selfTff7b72.Td2a8ffidentity_hashTffd700}Ta5d6ff"Tb4b4b4,
Tb4b4b4)
Tff7b72finallyTb4b4b4:
Tff7b72with Tff7b72selfTff7b72.Td2a8ff_deferred_setup_lockTb4b4b4:
Tff7b72selfTff7b72.Td2a8ff_deferred_setup_in_progress Tff7b72= Tff7b72False
Tff7b72selfTff7b72.Td2a8ff_deferred_setup_finishedTff7b72.Td2a8ffsetTb4b4b4(Tb4b4b4)

Tff7b72def Td2a8ff_deferred_still_activeTb4b4b4(Tff7b72selfTb4b4b4) Tff7b72-Tff7b72> Tffa657boolTb4b4b4:
Tff7b72return Tffa657boolTb4b4b4(Tff7b72selfTff7b72.Td2a8ffrunningTb4b4b4)

Tff7b72def Td2a8ff_run_deferred_services_bodyTb4b4b4(Tff7b72selfTb4b4b4)Tb4b4b4:
Tff7b72if Tff7b72not Tff7b72selfTff7b72.Td2a8ff_deferred_still_activeTb4b4b4(Tb4b4b4)Tb4b4b4:
Tff7b72return

Tff7b72tryTb4b4b4:
Tff7b72if Tff7b72not Tff7b72selfTff7b72.Td2a8ff_deferred_still_activeTb4b4b4(Tb4b4b4)Tb4b4b4:
Tff7b72return
Tff7b72selfTff7b72.Td2a8ffmap_overlay_manager Tff7b72= Te6edf3MapOverlayManagerTb4b4b4(
Tff7b72selfTff7b72.Td2a8ffconfigTb4b4b4,
Tff7b72selfTff7b72.Td2a8ffdatabaseTb4b4b4,
Tff7b72selfTff7b72.Td2a8ffstorage_pathTb4b4b4,
Te6edf3reticulum_config_dirTff7b72=Tffa657getattrTb4b4b4(Tff7b72selfTff7b72.Td2a8ffappTb4b4b4, Ta5d6ff"Ta5d6ffreticulum_config_dirTa5d6ff"Tb4b4b4, Tff7b72NoneTb4b4b4)Tb4b4b4,
Te6edf3identityTff7b72=Tff7b72selfTff7b72.Td2a8ffidentityTb4b4b4,
Te6edf3reticulumTff7b72=Tffa657getattrTb4b4b4(Tff7b72selfTff7b72.Td2a8ffappTb4b4b4, Ta5d6ff"Ta5d6ffreticulumTa5d6ff"Tb4b4b4, Tff7b72NoneTb4b4b4)Tb4b4b4,
Tb4b4b4)
Tff7b72tryTb4b4b4:
Tff7b72selfTff7b72.Td2a8ffmap_overlay_managerTff7b72.Td2a8ffstart_schedulerTb4b4b4(Tb4b4b4)
Tff7b72except Tf85149ExceptionTb4b4b4:
Tff7b72pass
Tff7b72except Tf85149Exception Tff7b72as Te6edf3excTb4b4b4:
Tffa657printTb4b4b4(Ta5d6fffTa5d6ff"Ta5d6ffFailed to start map overlay manager: Tffd700{Te6edf3excTffd700}Ta5d6ff"Tb4b4b4)

Tff7b72tryTb4b4b4:
Tff7b72if Tff7b72selfTff7b72.Td2a8ffdocs_manager Tff7b72is Tff7b72not Tff7b72None Tff7b72and Tff7b72selfTff7b72.Td2a8ff_deferred_still_activeTb4b4b4(Tb4b4b4)Tb4b4b4:
Tff7b72selfTff7b72.Td2a8ffdocs_managerTff7b72.Td2a8ffensure_meshchatx_docs_populatedTb4b4b4(Tb4b4b4)
Tff7b72except Tf85149Exception Tff7b72as Te6edf3excTb4b4b4:
Tffa657printTb4b4b4(Ta5d6fffTa5d6ff"Ta5d6ffFailed to populate docs: Tffd700{Te6edf3excTffd700}Ta5d6ff"Tb4b4b4)

Tff7b72if Tff7b72not Tff7b72selfTff7b72.Td2a8ff_deferred_still_activeTb4b4b4(Tb4b4b4)Tb4b4b4:
Tff7b72return

Tff7b72tryTb4b4b4:
Tff7b72selfTff7b72.Td2a8ffrncp_handler Tff7b72= Te6edf3RNCPHandlerTb4b4b4(
Te6edf3reticulum_instanceTff7b72=Tffa657getattrTb4b4b4(Tff7b72selfTff7b72.Td2a8ffappTb4b4b4, Ta5d6ff"Ta5d6ffreticulumTa5d6ff"Tb4b4b4, Tff7b72NoneTb4b4b4)Tb4b4b4,
Te6edf3identityTff7b72=Tff7b72selfTff7b72.Td2a8ffidentityTb4b4b4,
Te6edf3storage_dirTff7b72=Tff7b72selfTff7b72.Td2a8ffappTff7b72.Td2a8ffstorage_dirTb4b4b4,
Tb4b4b4)
Tff7b72selfTff7b72.Td2a8ffrncp_handlerTff7b72.Td2a8ffon_receive_completed Tff7b72= Tff7b72selfTff7b72.Td2a8ff_rncp_emit_receive_completed
Tff7b72if Tff7b72not Tff7b72selfTff7b72.Td2a8ff_deferred_still_activeTb4b4b4(Tb4b4b4)Tb4b4b4:
Tff7b72return
Tff7b72selfTff7b72.Td2a8ffrns_filesync_handler Tff7b72= Te6edf3RnsFilesyncHandlerTb4b4b4(
Te6edf3reticulum_instanceTff7b72=Tffa657getattrTb4b4b4(Tff7b72selfTff7b72.Td2a8ffappTb4b4b4, Ta5d6ff"Ta5d6ffreticulumTa5d6ff"Tb4b4b4, Tff7b72NoneTb4b4b4)Tb4b4b4,
Te6edf3identityTff7b72=Tff7b72selfTff7b72.Td2a8ffidentityTb4b4b4,
Te6edf3storage_dirTff7b72=Tff7b72selfTff7b72.Td2a8ffstorage_pathTb4b4b4,
Te6edf3emit_callbackTff7b72=Tff7b72selfTff7b72.Td2a8ff_filesync_emitTb4b4b4,
Tb4b4b4)
Tff7b72selfTff7b72.Td2a8ffrnsh_manager Tff7b72= Te6edf3RNSHManagerTb4b4b4(
Te6edf3storage_dirTff7b72=Tff7b72selfTff7b72.Td2a8ffstorage_pathTb4b4b4,
Te6edf3reticulum_config_dirTff7b72=Tffa657getattrTb4b4b4(Tff7b72selfTff7b72.Td2a8ffappTb4b4b4, Ta5d6ff"Ta5d6ffreticulum_config_dirTa5d6ff"Tb4b4b4, Tff7b72NoneTb4b4b4)Tb4b4b4,
Tb4b4b4)
Tff7b72selfTff7b72.Td2a8ffrnsh_managerTff7b72.Td2a8ffset_change_callbackTb4b4b4(
Tff7b72lambda Te6edf3sessionTb4b4b4: Tff7b72selfTff7b72.Td2a8ffappTff7b72.Td2a8ffon_rnsh_changeTb4b4b4(Te6edf3sessionTb4b4b4, Te6edf3contextTff7b72=Tff7b72selfTb4b4b4)Tb4b4b4,
Tb4b4b4)
Tff7b72selfTff7b72.Td2a8ffrnsh_managerTff7b72.Td2a8ffset_output_callbackTb4b4b4(
Tff7b72lambda Te6edf3sessionTb4b4b4, Te6edf3chunkTb4b4b4: Tff7b72selfTff7b72.Td2a8ffappTff7b72.Td2a8ffon_rnsh_outputTb4b4b4(
Te6edf3sessionTb4b4b4,
Te6edf3chunkTb4b4b4,
Te6edf3contextTff7b72=Tff7b72selfTb4b4b4,
Tb4b4b4)Tb4b4b4,
Tb4b4b4)
Tff7b72tryTb4b4b4:
Tff7b72selfTff7b72.Td2a8ffrnsh_managerTff7b72.Td2a8ffloadTb4b4b4(Tb4b4b4)
Tff7b72except Tf85149Exception Tff7b72as Te6edf3excTb4b4b4:
Tffa657printTb4b4b4(Ta5d6fffTa5d6ff"Ta5d6ffFailed to load RNSH sessions for Tffd700{Tff7b72selfTff7b72.Td2a8ffidentity_hashTffd700}Ta5d6ff: Tffd700{Te6edf3excTffd700}Ta5d6ff"Tb4b4b4)
Tff7b72if Tff7b72not Tff7b72selfTff7b72.Td2a8ff_deferred_still_activeTb4b4b4(Tb4b4b4)Tb4b4b4:
Tff7b72return
Tff7b72selfTff7b72.Td2a8ffrnx_manager Tff7b72= Te6edf3RNXManagerTb4b4b4(
Te6edf3storage_dirTff7b72=Tff7b72selfTff7b72.Td2a8ffstorage_pathTb4b4b4,
Te6edf3reticulum_config_dirTff7b72=Tffa657getattrTb4b4b4(Tff7b72selfTff7b72.Td2a8ffappTb4b4b4, Ta5d6ff"Ta5d6ffreticulum_config_dirTa5d6ff"Tb4b4b4, Tff7b72NoneTb4b4b4)Tb4b4b4,
Tb4b4b4)
Tff7b72selfTff7b72.Td2a8ffrnx_managerTff7b72.Td2a8ffset_change_callbackTb4b4b4(
Tff7b72lambda Te6edf3sessionTb4b4b4: Tff7b72selfTff7b72.Td2a8ffappTff7b72.Td2a8ffon_rnx_changeTb4b4b4(Te6edf3sessionTb4b4b4, Te6edf3contextTff7b72=Tff7b72selfTb4b4b4)Tb4b4b4,
Tb4b4b4)
Tff7b72selfTff7b72.Td2a8ffrnx_managerTff7b72.Td2a8ffset_output_callbackTb4b4b4(
Tff7b72lambda Te6edf3sessionTb4b4b4, Te6edf3chunkTb4b4b4: Tff7b72selfTff7b72.Td2a8ffappTff7b72.Td2a8ffon_rnx_outputTb4b4b4(
Te6edf3sessionTb4b4b4,
Te6edf3chunkTb4b4b4,
Te6edf3contextTff7b72=Tff7b72selfTb4b4b4,
Tb4b4b4)Tb4b4b4,
Tb4b4b4)
Tff7b72tryTb4b4b4:
Tff7b72selfTff7b72.Td2a8ffrnx_managerTff7b72.Td2a8ffloadTb4b4b4(Tb4b4b4)
Tff7b72except Tf85149Exception Tff7b72as Te6edf3excTb4b4b4:
Tffa657printTb4b4b4(Ta5d6fffTa5d6ff"Ta5d6ffFailed to load RNX sessions for Tffd700{Tff7b72selfTff7b72.Td2a8ffidentity_hashTffd700}Ta5d6ff: Tffd700{Te6edf3excTffd700}Ta5d6ff"Tb4b4b4)
Tff7b72selfTff7b72.Td2a8ffrnstatus_handler Tff7b72= Te6edf3RNStatusHandlerTb4b4b4(
Te6edf3reticulum_instanceTff7b72=Tffa657getattrTb4b4b4(Tff7b72selfTff7b72.Td2a8ffappTb4b4b4, Ta5d6ff"Ta5d6ffreticulumTa5d6ff"Tb4b4b4, Tff7b72NoneTb4b4b4)Tb4b4b4,
Tb4b4b4)
Tff7b72selfTff7b72.Td2a8ffrnpath_handler Tff7b72= Te6edf3RNPathHandlerTb4b4b4(
Te6edf3reticulum_instanceTff7b72=Tffa657getattrTb4b4b4(Tff7b72selfTff7b72.Td2a8ffappTb4b4b4, Ta5d6ff"Ta5d6ffreticulumTa5d6ff"Tb4b4b4, Tff7b72NoneTb4b4b4)Tb4b4b4,
Tb4b4b4)
Tff7b72selfTff7b72.Td2a8ffrnpath_trace_handler Tff7b72= Te6edf3RNPathTraceHandlerTb4b4b4(
Te6edf3reticulum_instanceTff7b72=Tffa657getattrTb4b4b4(Tff7b72selfTff7b72.Td2a8ffappTb4b4b4, Ta5d6ff"Ta5d6ffreticulumTa5d6ff"Tb4b4b4, Tff7b72NoneTb4b4b4)Tb4b4b4,
Te6edf3identityTff7b72=Tff7b72selfTff7b72.Td2a8ffidentityTb4b4b4,
Tb4b4b4)
Tff7b72selfTff7b72.Td2a8ffrnprobe_handler Tff7b72= Te6edf3RNProbeHandlerTb4b4b4(
Te6edf3reticulum_instanceTff7b72=Tffa657getattrTb4b4b4(Tff7b72selfTff7b72.Td2a8ffappTb4b4b4, Ta5d6ff"Ta5d6ffreticulumTa5d6ff"Tb4b4b4, Tff7b72NoneTb4b4b4)Tb4b4b4,
Te6edf3identityTff7b72=Tff7b72selfTff7b72.Td2a8ffidentityTb4b4b4,
Tb4b4b4)

Te6edf3libretranslate_url Tff7b72= Tff7b72selfTff7b72.Td2a8ffconfigTff7b72.Td2a8fflibretranslate_urlTff7b72.Td2a8ffgetTb4b4b4(Tb4b4b4)
Te6edf3libretranslate_api_key Tff7b72= Tff7b72selfTff7b72.Td2a8ffconfigTff7b72.Td2a8fflibretranslate_api_keyTff7b72.Td2a8ffgetTb4b4b4(Tb4b4b4)
Tff7b72selfTff7b72.Td2a8fftranslator_handler Tff7b72= Te6edf3TranslatorHandlerTb4b4b4(
Te6edf3libretranslate_urlTff7b72=Te6edf3libretranslate_urlTb4b4b4,
Te6edf3libretranslate_api_keyTff7b72=Te6edf3libretranslate_api_keyTb4b4b4,
Te6edf3translator_argos_enabledTff7b72=Tff7b72selfTff7b72.Td2a8ffconfigTff7b72.Td2a8fftranslator_argos_enabledTff7b72.Td2a8ffgetTb4b4b4(Tb4b4b4)Tb4b4b4,
Te6edf3translator_libretranslate_enabledTff7b72=Tff7b72selfTff7b72.Td2a8ffconfigTff7b72.Td2a8fftranslator_libretranslate_enabledTff7b72.Td2a8ffgetTb4b4b4(Tb4b4b4)Tb4b4b4,
Tb4b4b4)

Tff7b72selfTff7b72.Td2a8ffbot_handler Tff7b72= Te6edf3BotHandlerTb4b4b4(
Te6edf3identity_pathTff7b72=Tff7b72selfTff7b72.Td2a8ffstorage_pathTb4b4b4,
Te6edf3config_managerTff7b72=Tff7b72selfTff7b72.Td2a8ffconfigTb4b4b4,
Tb4b4b4)
Tff7b72tryTb4b4b4:
Tff7b72selfTff7b72.Td2a8ffbot_handlerTff7b72.Td2a8ffrestore_enabled_botsTb4b4b4(Tb4b4b4)
Tff7b72except Tf85149Exception Tff7b72as Te6edf3excTb4b4b4:
Tffa657printTb4b4b4(Ta5d6fffTa5d6ff"Ta5d6ffFailed to restore bots: Tffd700{Te6edf3excTffd700}Ta5d6ff"Tb4b4b4)
Tff7b72except Tf85149Exception Tff7b72as Te6edf3excTb4b4b4:
Tffa657printTb4b4b4(Ta5d6fffTa5d6ff"Ta5d6ffFailed deferred tool manager setup: Tffd700{Te6edf3excTffd700}Ta5d6ff"Tb4b4b4)

Tff7b72if Tff7b72not Tff7b72selfTff7b72.Td2a8ff_deferred_still_activeTb4b4b4(Tb4b4b4)Tb4b4b4:
Tff7b72return

Tff7b72tryTb4b4b4:
Te6edf3rrc_enabled Tff7b72= Tff7b72selfTff7b72.Td2a8ffconfigTff7b72.Td2a8ffrrc_enabledTff7b72.Td2a8ffgetTb4b4b4(Tb4b4b4) Tff7b72if Tff7b72selfTff7b72.Td2a8ffconfig Tff7b72else Tff7b72True
Tff7b72if Te6edf3rrc_enabledTb4b4b4:
Tff7b72selfTff7b72.Td2a8ffrrc_manager Tff7b72= Te6edf3RRCManagerTb4b4b4(
Te6edf3identityTff7b72=Tff7b72selfTff7b72.Td2a8ffidentityTb4b4b4,
Te6edf3storage_dirTff7b72=Tff7b72selfTff7b72.Td2a8ffstorage_pathTb4b4b4,
Te6edf3get_nicknameTff7b72=Tff7b72lambdaTb4b4b4: Tb4b4b4(
Tff7b72selfTff7b72.Td2a8ffconfigTff7b72.Td2a8ffdisplay_nameTff7b72.Td2a8ffgetTb4b4b4(Tb4b4b4) Tff7b72if Tff7b72selfTff7b72.Td2a8ffconfig Tff7b72else Tff7b72None
Tb4b4b4)Tb4b4b4,
Te6edf3get_name_for_identity_hashTff7b72=Tff7b72selfTff7b72.Td2a8ff_rrc_name_for_identity_hashTb4b4b4,
Te6edf3databaseTff7b72=Tff7b72selfTff7b72.Td2a8ffdatabaseTb4b4b4,
Tb4b4b4)
Tff7b72selfTff7b72.Td2a8ffrrc_managerTff7b72.Td2a8ffset_change_callbackTb4b4b4(
Tff7b72lambda Te6edf3hubTb4b4b4: Tff7b72selfTff7b72.Td2a8ffappTff7b72.Td2a8ffon_rrc_changeTb4b4b4(Te6edf3hubTb4b4b4, Te6edf3contextTff7b72=Tff7b72selfTb4b4b4)Tb4b4b4,
Tb4b4b4)
Tff7b72selfTff7b72.Td2a8ffrrc_managerTff7b72.Td2a8ffset_message_callbackTb4b4b4(
Tff7b72lambda Te6edf3hubTb4b4b4, Te6edf3msgTb4b4b4: Tff7b72selfTff7b72.Td2a8ffappTff7b72.Td2a8ffon_rrc_messageTb4b4b4(Te6edf3hubTb4b4b4, Te6edf3msgTb4b4b4, Te6edf3contextTff7b72=Tff7b72selfTb4b4b4)Tb4b4b4,
Tb4b4b4)
Tff7b72tryTb4b4b4:
Tff7b72selfTff7b72.Td2a8ffrrc_managerTff7b72.Td2a8ffloadTb4b4b4(Tb4b4b4)
Tff7b72except Tf85149Exception Tff7b72as Te6edf3excTb4b4b4:
Tffa657printTb4b4b4(Ta5d6fffTa5d6ff"Ta5d6ffFailed to load RRC hubs for Tffd700{Tff7b72selfTff7b72.Td2a8ffidentity_hashTffd700}Ta5d6ff: Tffd700{Te6edf3excTffd700}Ta5d6ff"Tb4b4b4)

Tff7b72selfTff7b72.Td2a8ffrrc_server_manager Tff7b72= Te6edf3RRCServerManagerTb4b4b4(
Te6edf3storage_dirTff7b72=Tff7b72selfTff7b72.Td2a8ffstorage_pathTb4b4b4,
Te6edf3owner_identityTff7b72=Tff7b72selfTff7b72.Td2a8ffidentityTff7b72.Td2a8ffhashTb4b4b4,
Tb4b4b4)
Tff7b72selfTff7b72.Td2a8ffrrc_server_managerTff7b72.Td2a8ffset_change_callbackTb4b4b4(
Tff7b72lambda Te6edf3hubTb4b4b4: Tff7b72selfTff7b72.Td2a8ffappTff7b72.Td2a8ffon_rrc_server_changeTb4b4b4(Te6edf3hubTb4b4b4, Te6edf3contextTff7b72=Tff7b72selfTb4b4b4)Tb4b4b4,
Tb4b4b4)
Tff7b72selfTff7b72.Td2a8ffrrc_managerTff7b72.Td2a8ffset_server_managerTb4b4b4(Tff7b72selfTff7b72.Td2a8ffrrc_server_managerTb4b4b4)
Tff7b72tryTb4b4b4:
Tff7b72selfTff7b72.Td2a8ffrrc_server_managerTff7b72.Td2a8ffloadTb4b4b4(Tb4b4b4)
Tff7b72except Tf85149Exception Tff7b72as Te6edf3excTb4b4b4:
Tffa657printTb4b4b4(
Ta5d6fffTa5d6ff"Ta5d6ffFailed to load RRC hub servers for Tffd700{Tff7b72selfTff7b72.Td2a8ffidentity_hashTffd700}Ta5d6ff: Tffd700{Te6edf3excTffd700}Ta5d6ff"Tb4b4b4,
Tb4b4b4)

Tff7b72tryTb4b4b4:
Tff7b72selfTff7b72.Td2a8ffrrc_managerTff7b72.Td2a8ffconnect_auto_reconnect_hubsTb4b4b4(Tb4b4b4)
Tff7b72except Tf85149Exception Tff7b72as Te6edf3excTb4b4b4:
Tffa657printTb4b4b4(
Ta5d6fffTa5d6ff"Ta5d6ffFailed to auto-connect RRC hubs for Tffd700{Tff7b72selfTff7b72.Td2a8ffidentity_hashTffd700}Ta5d6ff: Tffd700{Te6edf3excTffd700}Ta5d6ff"Tb4b4b4,
Tb4b4b4)
Tff7b72elseTb4b4b4:
Tff7b72selfTff7b72.Td2a8ffrrc_manager Tff7b72= Tff7b72None
Tff7b72selfTff7b72.Td2a8ffrrc_server_manager Tff7b72= Tff7b72None
Tff7b72except Tf85149Exception Tff7b72as Te6edf3excTb4b4b4:
Tffa657printTb4b4b4(Ta5d6fffTa5d6ff"Ta5d6ffFailed deferred RRC setup: Tffd700{Te6edf3excTffd700}Ta5d6ff"Tb4b4b4)

Tff7b72if Tff7b72not Tff7b72selfTff7b72.Td2a8ff_deferred_still_activeTb4b4b4(Tb4b4b4)Tb4b4b4:
Tff7b72return

Tff7b72if Tff7b72not Tffa657getattrTb4b4b4(Tff7b72selfTff7b72.Td2a8ffappTb4b4b4, Ta5d6ff"Ta5d6ffemergencyTa5d6ff"Tb4b4b4, Tff7b72FalseTb4b4b4)Tb4b4b4:
Tff7b72tryTb4b4b4:
Te6edf3is_okTb4b4b4, Te6edf3issues Tff7b72= Tff7b72selfTff7b72.Td2a8ffintegrity_managerTff7b72.Td2a8ffcheck_integrityTb4b4b4(Tb4b4b4)
Tff7b72if Tff7b72not Te6edf3is_okTb4b4b4:
Tffa657printTb4b4b4(
Ta5d6fffTa5d6ff"Ta5d6ffINTEGRITY WARNING (deferred) for Tffd700{Tff7b72selfTff7b72.Td2a8ffidentity_hashTffd700}Ta5d6ff: Tffd700{Ta5d6ff'Ta5d6ff, Ta5d6ff'Tff7b72.Td2a8ffjoinTb4b4b4(Te6edf3issuesTb4b4b4)Tffd700}Ta5d6ff"Tb4b4b4,
Tb4b4b4)
Tff7b72if Tff7b72not Tffa657hasattrTb4b4b4(Tff7b72selfTff7b72.Td2a8ffappTb4b4b4, Ta5d6ff"Ta5d6ffintegrity_issuesTa5d6ff"Tb4b4b4)Tb4b4b4:
Tff7b72selfTff7b72.Td2a8ffappTff7b72.Td2a8ffintegrity_issues Tff7b72= Tb4b4b4[Tb4b4b4]
Tff7b72for Te6edf3issue Tff7b72in Te6edf3issuesTb4b4b4:
Tff7b72if Te6edf3issue Tff7b72not Tff7b72in Tff7b72selfTff7b72.Td2a8ffappTff7b72.Td2a8ffintegrity_issuesTb4b4b4:
Tff7b72selfTff7b72.Td2a8ffappTff7b72.Td2a8ffintegrity_issuesTff7b72.Td2a8ffappendTb4b4b4(Te6edf3issueTb4b4b4)
Tff7b72if Tff7b72selfTff7b72.Td2a8ff_deferred_still_activeTb4b4b4(Tb4b4b4)Tb4b4b4:
Tff7b72selfTff7b72.Td2a8ffintegrity_managerTff7b72.Td2a8ffsave_manifestTb4b4b4(Tb4b4b4)
Tff7b72except Tf85149Exception Tff7b72as Te6edf3excTb4b4b4:
Tffa657printTb4b4b4(Ta5d6fffTa5d6ff"Ta5d6ffFailed deferred integrity pass: Tffd700{Te6edf3excTffd700}Ta5d6ff"Tb4b4b4)

Tff7b72tryTb4b4b4:
Tff7b72if Tff7b72not Tff7b72selfTff7b72.Td2a8ff_deferred_still_activeTb4b4b4(Tb4b4b4)Tb4b4b4:
Tff7b72return
Te6edf3full_db_issues Tff7b72= Tff7b72selfTff7b72.Td2a8ffdatabaseTff7b72.Td2a8ffcheck_db_health_at_openTb4b4b4(
Tff7b72selfTff7b72.Td2a8ffstorage_pathTb4b4b4,
Te6edf3quickTff7b72=Tff7b72FalseTb4b4b4,
Tb4b4b4)
Tff7b72if Te6edf3full_db_issuesTb4b4b4:
Te6edf3existing Tff7b72= Tffa657listTb4b4b4(
Tffa657getattrTb4b4b4(Tff7b72selfTff7b72.Td2a8ffappTb4b4b4, Ta5d6ff"Ta5d6ffdatabase_health_issuesTa5d6ff"Tb4b4b4, Tb4b4b4[Tb4b4b4]Tb4b4b4) Tff7b72or Tb4b4b4[Tb4b4b4]Tb4b4b4,
Tb4b4b4)
Tff7b72for Te6edf3issue Tff7b72in Te6edf3full_db_issuesTb4b4b4:
Tff7b72if Te6edf3issue Tff7b72not Tff7b72in Te6edf3existingTb4b4b4:
Te6edf3existingTff7b72.Td2a8ffappendTb4b4b4(Te6edf3issueTb4b4b4)
Tff7b72selfTff7b72.Td2a8ffappTff7b72.Td2a8ffdatabase_health_issues Tff7b72= Te6edf3existing
Tff7b72except Tf85149Exception Tff7b72as Te6edf3excTb4b4b4:
Tffa657printTb4b4b4(Ta5d6fffTa5d6ff"Ta5d6ffFailed deferred DB health check: Tffd700{Te6edf3excTffd700}Ta5d6ff"Tb4b4b4)

Tff7b72def Td2a8ffstart_background_threadsTb4b4b4(Tff7b72selfTb4b4b4)Tb4b4b4:
T8b949e# start background thread for auto announce loop
Te6edf3thread Tff7b72= Te6edf3threadingTff7b72.Td2a8ffThreadTb4b4b4(
Te6edf3targetTff7b72=Te6edf3asyncioTff7b72.Td2a8ffrunTb4b4b4,
Te6edf3argsTff7b72=Tb4b4b4(Tff7b72selfTff7b72.Td2a8ffappTff7b72.Td2a8ffannounce_loopTb4b4b4(Tff7b72selfTff7b72.Td2a8ffsession_idTb4b4b4, Te6edf3contextTff7b72=Tff7b72selfTb4b4b4)Tb4b4b4,Tb4b4b4)Tb4b4b4,
Tb4b4b4)
Te6edf3threadTff7b72.Td2a8ffdaemon Tff7b72= Tff7b72True
Te6edf3threadTff7b72.Td2a8ffstartTb4b4b4(Tb4b4b4)

T8b949e# start background thread for auto syncing propagation nodes
Te6edf3thread Tff7b72= Te6edf3threadingTff7b72.Td2a8ffThreadTb4b4b4(
Te6edf3targetTff7b72=Te6edf3asyncioTff7b72.Td2a8ffrunTb4b4b4,
Te6edf3argsTff7b72=Tb4b4b4(
Tff7b72selfTff7b72.Td2a8ffappTff7b72.Td2a8ffannounce_sync_propagation_nodesTb4b4b4(Tff7b72selfTff7b72.Td2a8ffsession_idTb4b4b4, Te6edf3contextTff7b72=Tff7b72selfTb4b4b4)Tb4b4b4,
Tb4b4b4)Tb4b4b4,
Tb4b4b4)
Te6edf3threadTff7b72.Td2a8ffdaemon Tff7b72= Tff7b72True
Te6edf3threadTff7b72.Td2a8ffstartTb4b4b4(Tb4b4b4)

T8b949e# start background thread for crawler loop
Te6edf3thread Tff7b72= Te6edf3threadingTff7b72.Td2a8ffThreadTb4b4b4(
Te6edf3targetTff7b72=Te6edf3asyncioTff7b72.Td2a8ffrunTb4b4b4,
Te6edf3argsTff7b72=Tb4b4b4(Tff7b72selfTff7b72.Td2a8ffappTff7b72.Td2a8ffcrawler_loopTb4b4b4(Tff7b72selfTff7b72.Td2a8ffsession_idTb4b4b4, Te6edf3contextTff7b72=Tff7b72selfTb4b4b4)Tb4b4b4,Tb4b4b4)Tb4b4b4,
Tb4b4b4)
Te6edf3threadTff7b72.Td2a8ffdaemon Tff7b72= Tff7b72True
Te6edf3threadTff7b72.Td2a8ffstartTb4b4b4(Tb4b4b4)

T8b949e# start background thread for auto backup loop
Te6edf3thread Tff7b72= Te6edf3threadingTff7b72.Td2a8ffThreadTb4b4b4(
Te6edf3targetTff7b72=Te6edf3asyncioTff7b72.Td2a8ffrunTb4b4b4,
Te6edf3argsTff7b72=Tb4b4b4(Tff7b72selfTff7b72.Td2a8ffappTff7b72.Td2a8ffauto_backup_loopTb4b4b4(Tff7b72selfTff7b72.Td2a8ffsession_idTb4b4b4, Te6edf3contextTff7b72=Tff7b72selfTb4b4b4)Tb4b4b4,Tb4b4b4)Tb4b4b4,
Tb4b4b4)
Te6edf3threadTff7b72.Td2a8ffdaemon Tff7b72= Tff7b72True
Te6edf3threadTff7b72.Td2a8ffstartTb4b4b4(Tb4b4b4)

T8b949e# start background thread for telemetry tracking loop
Te6edf3thread Tff7b72= Te6edf3threadingTff7b72.Td2a8ffThreadTb4b4b4(
Te6edf3targetTff7b72=Te6edf3asyncioTff7b72.Td2a8ffrunTb4b4b4,
Te6edf3argsTff7b72=Tb4b4b4(Tff7b72selfTff7b72.Td2a8ffappTff7b72.Td2a8fftelemetry_tracking_loopTb4b4b4(Tff7b72selfTff7b72.Td2a8ffsession_idTb4b4b4, Te6edf3contextTff7b72=Tff7b72selfTb4b4b4)Tb4b4b4,Tb4b4b4)Tb4b4b4,
Tb4b4b4)
Te6edf3threadTff7b72.Td2a8ffdaemon Tff7b72= Tff7b72True
Te6edf3threadTff7b72.Td2a8ffstartTb4b4b4(Tb4b4b4)

T8b949e# start background thread for local (device-only) message age retention
Te6edf3thread Tff7b72= Te6edf3threadingTff7b72.Td2a8ffThreadTb4b4b4(
Te6edf3targetTff7b72=Te6edf3asyncioTff7b72.Td2a8ffrunTb4b4b4,
Te6edf3argsTff7b72=Tb4b4b4(
Tff7b72selfTff7b72.Td2a8ffappTff7b72.Td2a8fflocal_message_retention_loopTb4b4b4(Tff7b72selfTff7b72.Td2a8ffsession_idTb4b4b4, Te6edf3contextTff7b72=Tff7b72selfTb4b4b4)Tb4b4b4,
Tb4b4b4)Tb4b4b4,
Tb4b4b4)
Te6edf3threadTff7b72.Td2a8ffdaemon Tff7b72= Tff7b72True
Te6edf3threadTff7b72.Td2a8ffstartTb4b4b4(Tb4b4b4)

T8b949e# start background thread for LXMF flood protection cooldown
Te6edf3thread Tff7b72= Te6edf3threadingTff7b72.Td2a8ffThreadTb4b4b4(
Te6edf3targetTff7b72=Te6edf3asyncioTff7b72.Td2a8ffrunTb4b4b4,
Te6edf3argsTff7b72=Tb4b4b4(
Tff7b72selfTff7b72.Td2a8ffappTff7b72.Td2a8fflxmf_flood_protection_cooldown_loopTb4b4b4(
Tff7b72selfTff7b72.Td2a8ffsession_idTb4b4b4,
Te6edf3contextTff7b72=Tff7b72selfTb4b4b4,
Tb4b4b4)Tb4b4b4,
Tb4b4b4)Tb4b4b4,
Tb4b4b4)
Te6edf3threadTff7b72.Td2a8ffdaemon Tff7b72= Tff7b72True
Te6edf3threadTff7b72.Td2a8ffstartTb4b4b4(Tb4b4b4)

T8b949e# start background thread for auto propagation node selection
Te6edf3thread Tff7b72= Te6edf3threadingTff7b72.Td2a8ffThreadTb4b4b4(
Te6edf3targetTff7b72=Te6edf3asyncioTff7b72.Td2a8ffrunTb4b4b4,
Te6edf3argsTff7b72=Tb4b4b4(Tff7b72selfTff7b72.Td2a8ffauto_propagation_managerTff7b72.Td2a8ff_runTb4b4b4(Tb4b4b4)Tb4b4b4,Tb4b4b4)Tb4b4b4,
Tb4b4b4)
Te6edf3threadTff7b72.Td2a8ffdaemon Tff7b72= Tff7b72True
Te6edf3threadTff7b72.Td2a8ffstartTb4b4b4(Tb4b4b4)

Tff7b72def Td2a8ffregister_announce_handlersTb4b4b4(Tff7b72selfTb4b4b4)Tb4b4b4:
Te6edf3handlers Tff7b72= Tb4b4b4[
Te6edf3AnnounceHandlerTb4b4b4(
Ta5d6ff"Ta5d6fflxst.telephonyTa5d6ff"Tb4b4b4,
Tff7b72lambda Te6edf3aspectTb4b4b4, Te6edf3dhTb4b4b4, Te6edf3aiTb4b4b4, Te6edf3adTb4b4b4, Te6edf3aphTb4b4b4: Tff7b72selfTff7b72.Td2a8ffappTff7b72.Td2a8ffon_telephone_announce_receivedTb4b4b4(
Te6edf3aspectTb4b4b4,
Te6edf3dhTb4b4b4,
Te6edf3aiTb4b4b4,
Te6edf3adTb4b4b4,
Te6edf3aphTb4b4b4,
Te6edf3contextTff7b72=Tff7b72selfTb4b4b4,
Tb4b4b4)Tb4b4b4,
Tb4b4b4)Tb4b4b4,
Te6edf3AnnounceHandlerTb4b4b4(
Ta5d6ff"Ta5d6fflxmf.deliveryTa5d6ff"Tb4b4b4,
Tff7b72lambda Te6edf3aspectTb4b4b4, Te6edf3dhTb4b4b4, Te6edf3aiTb4b4b4, Te6edf3adTb4b4b4, Te6edf3aphTb4b4b4: Tff7b72selfTff7b72.Td2a8ffappTff7b72.Td2a8ffon_lxmf_announce_receivedTb4b4b4(
Te6edf3aspectTb4b4b4,
Te6edf3dhTb4b4b4,
Te6edf3aiTb4b4b4,
Te6edf3adTb4b4b4,
Te6edf3aphTb4b4b4,
Te6edf3contextTff7b72=Tff7b72selfTb4b4b4,
Tb4b4b4)Tb4b4b4,
Tb4b4b4)Tb4b4b4,
Te6edf3AnnounceHandlerTb4b4b4(
Ta5d6ff"Ta5d6fflxmf.propagationTa5d6ff"Tb4b4b4,
Tff7b72lambda Te6edf3aspectTb4b4b4, Te6edf3dhTb4b4b4, Te6edf3aiTb4b4b4, Te6edf3adTb4b4b4, Te6edf3aphTb4b4b4: Tb4b4b4(
Tff7b72selfTff7b72.Td2a8ffappTff7b72.Td2a8ffon_lxmf_propagation_announce_receivedTb4b4b4(
Te6edf3aspectTb4b4b4,
Te6edf3dhTb4b4b4,
Te6edf3aiTb4b4b4,
Te6edf3adTb4b4b4,
Te6edf3aphTb4b4b4,
Te6edf3contextTff7b72=Tff7b72selfTb4b4b4,
Tb4b4b4)
Tb4b4b4)Tb4b4b4,
Tb4b4b4)Tb4b4b4,
Te6edf3AnnounceHandlerTb4b4b4(
Ta5d6ff"Ta5d6ffnomadnetwork.nodeTa5d6ff"Tb4b4b4,
Tff7b72lambda Te6edf3aspectTb4b4b4, Te6edf3dhTb4b4b4, Te6edf3aiTb4b4b4, Te6edf3adTb4b4b4, Te6edf3aphTb4b4b4: Tb4b4b4(
Tff7b72selfTff7b72.Td2a8ffappTff7b72.Td2a8ffon_nomadnet_node_announce_receivedTb4b4b4(
Te6edf3aspectTb4b4b4,
Te6edf3dhTb4b4b4,
Te6edf3aiTb4b4b4,
Te6edf3adTb4b4b4,
Te6edf3aphTb4b4b4,
Te6edf3contextTff7b72=Tff7b72selfTb4b4b4,
Tb4b4b4)
Tb4b4b4)Tb4b4b4,
Tb4b4b4)Tb4b4b4,
Tff7b72*Tb4b4b4(
Tb4b4b4[
Te6edf3AnnounceHandlerTb4b4b4(
Ta5d6ff"Ta5d6ffrrc.hubTa5d6ff"Tb4b4b4,
Tff7b72lambda Te6edf3aspectTb4b4b4, Te6edf3dhTb4b4b4, Te6edf3aiTb4b4b4, Te6edf3adTb4b4b4, Te6edf3aphTb4b4b4: Tb4b4b4(
Tff7b72selfTff7b72.Td2a8ffappTff7b72.Td2a8ffon_rrc_hub_announce_receivedTb4b4b4(
Te6edf3aspectTb4b4b4,
Te6edf3dhTb4b4b4,
Te6edf3aiTb4b4b4,
Te6edf3adTb4b4b4,
Te6edf3aphTb4b4b4,
Te6edf3contextTff7b72=Tff7b72selfTb4b4b4,
Tb4b4b4)
Tb4b4b4)Tb4b4b4,
Tb4b4b4)Tb4b4b4,
Tb4b4b4]
Tff7b72if Tff7b72selfTff7b72.Td2a8ffconfig Tff7b72and Tff7b72selfTff7b72.Td2a8ffconfigTff7b72.Td2a8ffrrc_enabledTff7b72.Td2a8ffgetTb4b4b4(Tb4b4b4)
Tff7b72else Tb4b4b4[Tb4b4b4]
Tb4b4b4)Tb4b4b4,
Tb4b4b4]
Tff7b72for Te6edf3handler Tff7b72in Te6edf3handlersTb4b4b4:
Te6edf3RNSTff7b72.Td2a8ffTransportTff7b72.Td2a8ffregister_announce_handlerTb4b4b4(Te6edf3handlerTb4b4b4)
Tff7b72selfTff7b72.Td2a8ffannounce_handlersTff7b72.Td2a8ffappendTb4b4b4(Te6edf3handlerTb4b4b4)

Tff7b72def Td2a8ffteardownTb4b4b4(Tff7b72selfTb4b4b4)Tb4b4b4:
Tffa657printTb4b4b4(Ta5d6fffTa5d6ff"Ta5d6ffTearing down Identity Context for Tffd700{Tff7b72selfTff7b72.Td2a8ffidentity_hashTffd700}Ta5d6ff...Ta5d6ff"Tb4b4b4)
Tff7b72selfTff7b72.Td2a8ffrunning Tff7b72= Tff7b72False
T8b949e# Let an in-flight deferred setup notice running=False and exit before
T8b949e# we null managers it may still be assigning.
Te6edf3finished Tff7b72= Tffa657getattrTb4b4b4(Tff7b72selfTb4b4b4, Ta5d6ff"Ta5d6ff_deferred_setup_finishedTa5d6ff"Tb4b4b4, Tff7b72NoneTb4b4b4)
Tff7b72if Te6edf3finished Tff7b72is Tff7b72not Tff7b72None Tff7b72and Tff7b72not Te6edf3finishedTff7b72.Td2a8ffwaitTb4b4b4(Te6edf3timeoutTff7b72=T79c0ff30Tb4b4b4)Tb4b4b4:
Tffa657printTb4b4b4(
Ta5d6fffTa5d6ff"Ta5d6ffTimed out waiting for deferred setup during teardown of Tffd700{Tff7b72selfTff7b72.Td2a8ffidentity_hashTffd700}Ta5d6ff"Tb4b4b4,
Tb4b4b4)
Tff7b72if Tff7b72selfTff7b72.Td2a8ffauto_propagation_managerTb4b4b4:
Tff7b72selfTff7b72.Td2a8ffauto_propagation_managerTff7b72.Td2a8ffstopTb4b4b4(Tb4b4b4)
Tff7b72selfTff7b72.Td2a8ffauto_propagation_manager Tff7b72= Tff7b72None

Tff7b72if Tff7b72selfTff7b72.Td2a8ffbot_handlerTb4b4b4:
Tff7b72tryTb4b4b4:
Tff7b72selfTff7b72.Td2a8ffbot_handlerTff7b72.Td2a8ffstop_allTb4b4b4(Tb4b4b4)
Tff7b72except Tf85149Exception Tff7b72as Te6edf3eTb4b4b4:
Tffa657printTb4b4b4(Ta5d6fffTa5d6ff"Ta5d6ffError while stopping bots for Tffd700{Tff7b72selfTff7b72.Td2a8ffidentity_hashTffd700}Ta5d6ff: Tffd700{Te6edf3eTffd700}Ta5d6ff"Tb4b4b4)
Tff7b72selfTff7b72.Td2a8ffbot_handler Tff7b72= Tff7b72None

T8b949e# 1. Deregister announce handlers
Tff7b72for Te6edf3handler Tff7b72in Tff7b72selfTff7b72.Td2a8ffannounce_handlersTb4b4b4:
Tff7b72with Te6edf3contextlibTff7b72.Td2a8ffsuppressTb4b4b4(Tf85149ExceptionTb4b4b4)Tb4b4b4:
Te6edf3RNSTff7b72.Td2a8ffTransportTff7b72.Td2a8ffderegister_announce_handlerTb4b4b4(Te6edf3handlerTb4b4b4)
Tff7b72selfTff7b72.Td2a8ffannounce_handlers Tff7b72= Tb4b4b4[Tb4b4b4]

Tff7b72if Tff7b72selfTff7b72.Td2a8ffrrc_managerTb4b4b4:
Tff7b72tryTb4b4b4:
Tff7b72selfTff7b72.Td2a8ffrrc_managerTff7b72.Td2a8ffset_change_callbackTb4b4b4(Tff7b72NoneTb4b4b4)
Tff7b72selfTff7b72.Td2a8ffrrc_managerTff7b72.Td2a8ffset_message_callbackTb4b4b4(Tff7b72NoneTb4b4b4)
Tff7b72selfTff7b72.Td2a8ffrrc_managerTff7b72.Td2a8ffshutdownTb4b4b4(Tb4b4b4)
Tff7b72except Tf85149Exception Tff7b72as Te6edf3eTb4b4b4:
Tffa657printTb4b4b4(
Ta5d6fffTa5d6ff"Ta5d6ffError tearing down RRC manager for Tffd700{Tff7b72selfTff7b72.Td2a8ffidentity_hashTffd700}Ta5d6ff: Tffd700{Te6edf3eTffd700}Ta5d6ff"Tb4b4b4,
Tb4b4b4)
Tff7b72selfTff7b72.Td2a8ffrrc_manager Tff7b72= Tff7b72None

Tff7b72if Tff7b72selfTff7b72.Td2a8ffrrc_server_managerTb4b4b4:
Tff7b72tryTb4b4b4:
Tff7b72selfTff7b72.Td2a8ffrrc_server_managerTff7b72.Td2a8ffset_change_callbackTb4b4b4(Tff7b72NoneTb4b4b4)
Tff7b72selfTff7b72.Td2a8ffrrc_server_managerTff7b72.Td2a8ffshutdownTb4b4b4(Tb4b4b4)
Tff7b72except Tf85149Exception Tff7b72as Te6edf3eTb4b4b4:
Tffa657printTb4b4b4(
Ta5d6fffTa5d6ff"Ta5d6ffError tearing down RRC hub servers for Tffd700{Tff7b72selfTff7b72.Td2a8ffidentity_hashTffd700}Ta5d6ff: Tffd700{Te6edf3eTffd700}Ta5d6ff"Tb4b4b4,
Tb4b4b4)
Tff7b72selfTff7b72.Td2a8ffrrc_server_manager Tff7b72= Tff7b72None

Tff7b72if Tff7b72selfTff7b72.Td2a8ffrnsh_managerTb4b4b4:
Tff7b72tryTb4b4b4:
Tff7b72selfTff7b72.Td2a8ffrnsh_managerTff7b72.Td2a8ffset_change_callbackTb4b4b4(Tff7b72NoneTb4b4b4)
Tff7b72selfTff7b72.Td2a8ffrnsh_managerTff7b72.Td2a8ffset_output_callbackTb4b4b4(Tff7b72NoneTb4b4b4)
Tff7b72selfTff7b72.Td2a8ffrnsh_managerTff7b72.Td2a8ffshutdownTb4b4b4(Tb4b4b4)
Tff7b72except Tf85149Exception Tff7b72as Te6edf3eTb4b4b4:
Tffa657printTb4b4b4(
Ta5d6fffTa5d6ff"Ta5d6ffError tearing down RNSH manager for Tffd700{Tff7b72selfTff7b72.Td2a8ffidentity_hashTffd700}Ta5d6ff: Tffd700{Te6edf3eTffd700}Ta5d6ff"Tb4b4b4,
Tb4b4b4)
Tff7b72selfTff7b72.Td2a8ffrnsh_manager Tff7b72= Tff7b72None

Tff7b72if Tff7b72selfTff7b72.Td2a8ffrnx_managerTb4b4b4:
Tff7b72tryTb4b4b4:
Tff7b72selfTff7b72.Td2a8ffrnx_managerTff7b72.Td2a8ffset_change_callbackTb4b4b4(Tff7b72NoneTb4b4b4)
Tff7b72selfTff7b72.Td2a8ffrnx_managerTff7b72.Td2a8ffset_output_callbackTb4b4b4(Tff7b72NoneTb4b4b4)
Tff7b72selfTff7b72.Td2a8ffrnx_managerTff7b72.Td2a8ffshutdownTb4b4b4(Tb4b4b4)
Tff7b72except Tf85149Exception Tff7b72as Te6edf3eTb4b4b4:
Tffa657printTb4b4b4(
Ta5d6fffTa5d6ff"Ta5d6ffError tearing down RNX manager for Tffd700{Tff7b72selfTff7b72.Td2a8ffidentity_hashTffd700}Ta5d6ff: Tffd700{Te6edf3eTffd700}Ta5d6ff"Tb4b4b4,
Tb4b4b4)
Tff7b72selfTff7b72.Td2a8ffrnx_manager Tff7b72= Tff7b72None

Tff7b72if Tff7b72selfTff7b72.Td2a8ffforwarding_managerTb4b4b4:
Tff7b72tryTb4b4b4:
Tff7b72selfTff7b72.Td2a8ffforwarding_managerTff7b72.Td2a8ffteardownTb4b4b4(Tb4b4b4)
Tff7b72except Tf85149Exception Tff7b72as Te6edf3eTb4b4b4:
Tffa657printTb4b4b4(
Ta5d6fffTa5d6ff"Ta5d6ffError tearing down forwarding manager for Tffd700{Tff7b72selfTff7b72.Td2a8ffidentity_hashTffd700}Ta5d6ff: Tffd700{Te6edf3eTffd700}Ta5d6ff"Tb4b4b4,
Tb4b4b4)
Tff7b72selfTff7b72.Td2a8ffforwarding_manager Tff7b72= Tff7b72None

T8b949e# 2. Cleanup RNS destinations and links
Tff7b72tryTb4b4b4:
Tff7b72if Tff7b72selfTff7b72.Td2a8ffrncp_handlerTb4b4b4:
Tff7b72with Te6edf3contextlibTff7b72.Td2a8ffsuppressTb4b4b4(Tf85149ExceptionTb4b4b4)Tb4b4b4:
Tff7b72selfTff7b72.Td2a8ffrncp_handlerTff7b72.Td2a8ffteardown_receive_destinationTb4b4b4(Tb4b4b4)
Tff7b72selfTff7b72.Td2a8ffrncp_handler Tff7b72= Tff7b72None

Tff7b72if Tff7b72selfTff7b72.Td2a8ffrns_filesync_handlerTb4b4b4:
Tff7b72with Te6edf3contextlibTff7b72.Td2a8ffsuppressTb4b4b4(Tf85149ExceptionTb4b4b4)Tb4b4b4:
Tff7b72selfTff7b72.Td2a8ffrns_filesync_handlerTff7b72.Td2a8ffteardownTb4b4b4(Tb4b4b4)
Tff7b72selfTff7b72.Td2a8ffrns_filesync_handler Tff7b72= Tff7b72None

Tff7b72selfTff7b72.Td2a8ffrnstatus_handler Tff7b72= Tff7b72None
Tff7b72selfTff7b72.Td2a8ffrnpath_handler Tff7b72= Tff7b72None
Tff7b72selfTff7b72.Td2a8ffrnpath_trace_handler Tff7b72= Tff7b72None
Tff7b72selfTff7b72.Td2a8ffrnprobe_handler Tff7b72= Tff7b72None

Tff7b72if Tff7b72selfTff7b72.Td2a8ffmessage_routerTb4b4b4:
T8b949e# Break cycles in mocks/objects
Tff7b72if Tffa657hasattrTb4b4b4(Tff7b72selfTff7b72.Td2a8ffmessage_routerTb4b4b4, Ta5d6ff"Ta5d6ffregister_delivery_callbackTa5d6ff"Tb4b4b4)Tb4b4b4:
Tff7b72with Te6edf3contextlibTff7b72.Td2a8ffsuppressTb4b4b4(Tf85149ExceptionTb4b4b4)Tb4b4b4:
Tff7b72selfTff7b72.Td2a8ffmessage_routerTff7b72.Td2a8ffregister_delivery_callbackTb4b4b4(Tff7b72NoneTb4b4b4)

Tff7b72if Tffa657hasattrTb4b4b4(Tff7b72selfTff7b72.Td2a8ffmessage_routerTb4b4b4, Ta5d6ff"Ta5d6ffdelivery_destinationsTa5d6ff"Tb4b4b4)Tb4b4b4:
Tff7b72for Te6edf3dest_hash Tff7b72in Tffa657listTb4b4b4(
Tff7b72selfTff7b72.Td2a8ffmessage_routerTff7b72.Td2a8ffdelivery_destinationsTff7b72.Td2a8ffkeysTb4b4b4(Tb4b4b4)Tb4b4b4,
Tb4b4b4)Tb4b4b4:
Te6edf3dest Tff7b72= Tff7b72selfTff7b72.Td2a8ffmessage_routerTff7b72.Td2a8ffdelivery_destinationsTb4b4b4[Te6edf3dest_hashTb4b4b4]
Te6edf3RNSTff7b72.Td2a8ffTransportTff7b72.Td2a8ffderegister_destinationTb4b4b4(Te6edf3destTb4b4b4)

Tff7b72if Tb4b4b4(
Tffa657hasattrTb4b4b4(Tff7b72selfTff7b72.Td2a8ffmessage_routerTb4b4b4, Ta5d6ff"Ta5d6ffpropagation_destinationTa5d6ff"Tb4b4b4)
Tff7b72and Tff7b72selfTff7b72.Td2a8ffmessage_routerTff7b72.Td2a8ffpropagation_destination
Tb4b4b4)Tb4b4b4:
Te6edf3RNSTff7b72.Td2a8ffTransportTff7b72.Td2a8ffderegister_destinationTb4b4b4(
Tff7b72selfTff7b72.Td2a8ffmessage_routerTff7b72.Td2a8ffpropagation_destinationTb4b4b4,
Tb4b4b4)

Tff7b72if Tff7b72selfTff7b72.Td2a8fftelephone_manager Tff7b72and Tff7b72selfTff7b72.Td2a8fftelephone_managerTff7b72.Td2a8fftelephoneTb4b4b4:
Tff7b72if Tb4b4b4(
Tffa657hasattrTb4b4b4(Tff7b72selfTff7b72.Td2a8fftelephone_managerTff7b72.Td2a8fftelephoneTb4b4b4, Ta5d6ff"Ta5d6ffdestinationTa5d6ff"Tb4b4b4)
Tff7b72and Tff7b72selfTff7b72.Td2a8fftelephone_managerTff7b72.Td2a8fftelephoneTff7b72.Td2a8ffdestination
Tb4b4b4)Tb4b4b4:
Te6edf3RNSTff7b72.Td2a8ffTransportTff7b72.Td2a8ffderegister_destinationTb4b4b4(
Tff7b72selfTff7b72.Td2a8fftelephone_managerTff7b72.Td2a8fftelephoneTff7b72.Td2a8ffdestinationTb4b4b4,
Tb4b4b4)

Tff7b72selfTff7b72.Td2a8ffappTff7b72.Td2a8ffcleanup_rns_state_for_identityTb4b4b4(Tff7b72selfTff7b72.Td2a8ffidentityTff7b72.Td2a8ffhashTb4b4b4)
Tff7b72except Tf85149Exception Tff7b72as Te6edf3eTb4b4b4:
Tffa657printTb4b4b4(Ta5d6fffTa5d6ff"Ta5d6ffError during RNS cleanup for Tffd700{Tff7b72selfTff7b72.Td2a8ffidentity_hashTffd700}Ta5d6ff: Tffd700{Te6edf3eTffd700}Ta5d6ff"Tb4b4b4)

T8b949e# 3. Stop LXMF Router jobs
Tff7b72if Tff7b72selfTff7b72.Td2a8ffmessage_routerTb4b4b4:
Tff7b72tryTb4b4b4:
Tff7b72selfTff7b72.Td2a8ffmessage_routerTff7b72.Td2a8ffjobs Tff7b72= Tff7b72lambdaTb4b4b4: Tff7b72None
Tff7b72if Tffa657hasattrTb4b4b4(Tff7b72selfTff7b72.Td2a8ffmessage_routerTb4b4b4, Ta5d6ff"Ta5d6ffexit_handlerTa5d6ff"Tb4b4b4)Tb4b4b4:
Tff7b72selfTff7b72.Td2a8ffmessage_routerTff7b72.Td2a8ffexit_handlerTb4b4b4(Tb4b4b4)

T8b949e# Give LXMF/RNS a moment to finish any final disk writes
Tff7b72import T7ee787time

Te6edf3timeTff7b72.Td2a8ffsleepTb4b4b4(T79c0ff1.0Tb4b4b4)
Tff7b72except Tf85149Exception Tff7b72as Te6edf3eTb4b4b4:
Tffa657printTb4b4b4(
Ta5d6fffTa5d6ff"Ta5d6ffError while tearing down LXMRouter for Tffd700{Tff7b72selfTff7b72.Td2a8ffidentity_hashTffd700}Ta5d6ff: Tffd700{Te6edf3eTffd700}Ta5d6ff"Tb4b4b4,
Tb4b4b4)
Tff7b72selfTff7b72.Td2a8ffmessage_router Tff7b72= Tff7b72None

T8b949e# 4. Stop telephone and voicemail
Tff7b72if Tff7b72selfTff7b72.Td2a8fftelephone_managerTb4b4b4:
Tff7b72tryTb4b4b4:
T8b949e# Clear callbacks to break reference cycles
Tff7b72selfTff7b72.Td2a8fftelephone_managerTff7b72.Td2a8ffon_initiation_status_callback Tff7b72= Tff7b72None
Tff7b72selfTff7b72.Td2a8fftelephone_managerTff7b72.Td2a8ffget_name_for_identity_hash Tff7b72= Tff7b72None

Tff7b72selfTff7b72.Td2a8fftelephone_managerTff7b72.Td2a8ffteardownTb4b4b4(Tb4b4b4)
Tff7b72except Tf85149Exception Tff7b72as Te6edf3eTb4b4b4:
Tffa657printTb4b4b4(
Ta5d6fffTa5d6ff"Ta5d6ffError while tearing down telephone for Tffd700{Tff7b72selfTff7b72.Td2a8ffidentity_hashTffd700}Ta5d6ff: Tffd700{Te6edf3eTffd700}Ta5d6ff"Tb4b4b4,
Tb4b4b4)
Tff7b72selfTff7b72.Td2a8fftelephone_manager Tff7b72= Tff7b72None

Tff7b72if Tff7b72selfTff7b72.Td2a8ffvoicemail_managerTb4b4b4:
Tff7b72with Te6edf3contextlibTff7b72.Td2a8ffsuppressTb4b4b4(Tf85149ExceptionTb4b4b4)Tb4b4b4:
Tff7b72selfTff7b72.Td2a8ffvoicemail_managerTff7b72.Td2a8ffon_new_voicemail_callback Tff7b72= Tff7b72None
Tff7b72selfTff7b72.Td2a8ffvoicemail_managerTff7b72.Td2a8ffget_name_for_identity_hash Tff7b72= Tff7b72None
Tff7b72selfTff7b72.Td2a8ffvoicemail_manager Tff7b72= Tff7b72None

Tff7b72if Tff7b72selfTff7b72.Td2a8ffmessage_handlerTb4b4b4:
Tff7b72selfTff7b72.Td2a8ffmessage_handler Tff7b72= Tff7b72None

Tff7b72if Tff7b72selfTff7b72.Td2a8ffannounce_managerTb4b4b4:
Tff7b72selfTff7b72.Td2a8ffannounce_manager Tff7b72= Tff7b72None

Tff7b72if Tff7b72selfTff7b72.Td2a8ffarchiver_managerTb4b4b4:
Tff7b72selfTff7b72.Td2a8ffarchiver_manager Tff7b72= Tff7b72None

Tff7b72if Tff7b72selfTff7b72.Td2a8ffmap_overlay_managerTb4b4b4:
Tff7b72tryTb4b4b4:
Tff7b72selfTff7b72.Td2a8ffmap_overlay_managerTff7b72.Td2a8ffcleanupTb4b4b4(Tb4b4b4)
Tff7b72except Tf85149ExceptionTb4b4b4:
Tff7b72pass
Tff7b72selfTff7b72.Td2a8ffmap_overlay_manager Tff7b72= Tff7b72None
Tff7b72if Tff7b72selfTff7b72.Td2a8ffmap_managerTb4b4b4:
Tff7b72selfTff7b72.Td2a8ffmap_manager Tff7b72= Tff7b72None

Tff7b72if Tff7b72selfTff7b72.Td2a8ffdocs_managerTb4b4b4:
Tff7b72selfTff7b72.Td2a8ffdocs_manager Tff7b72= Tff7b72None

Tff7b72if Tff7b72selfTff7b72.Td2a8ffrepository_server_managerTb4b4b4:
Tff7b72with Te6edf3contextlibTff7b72.Td2a8ffsuppressTb4b4b4(Tf85149ExceptionTb4b4b4)Tb4b4b4:
Tff7b72selfTff7b72.Td2a8ffrepository_server_managerTff7b72.Td2a8ffstop_http_serverTb4b4b4(Tb4b4b4)
Tff7b72selfTff7b72.Td2a8ffrepository_server_manager Tff7b72= Tff7b72None

Tff7b72if Tff7b72selfTff7b72.Td2a8ffnomadnet_managerTb4b4b4:
Tff7b72selfTff7b72.Td2a8ffnomadnet_manager Tff7b72= Tff7b72None

Tff7b72if Tff7b72selfTff7b72.Td2a8ffdatabaseTb4b4b4:
Tff7b72tryTb4b4b4:
Tff7b72if Tff7b72not Tffa657getattrTb4b4b4(Tff7b72selfTff7b72.Td2a8ffappTb4b4b4, Ta5d6ff"Ta5d6ffemergencyTa5d6ff"Tb4b4b4, Tff7b72FalseTb4b4b4)Tb4b4b4:
Te6edf3close_issues Tff7b72= Tff7b72selfTff7b72.Td2a8ffdatabaseTff7b72.Td2a8ffcheck_db_health_at_closeTb4b4b4(
Tff7b72selfTff7b72.Td2a8ffstorage_pathTb4b4b4,
Tb4b4b4)
Tff7b72if Te6edf3close_issuesTb4b4b4:
Tffa657printTb4b4b4(
Ta5d6fffTa5d6ff"Ta5d6ffDatabase health at close for Tffd700{Tff7b72selfTff7b72.Td2a8ffidentity_hashTffd700}Ta5d6ff: Tffd700{Ta5d6ff'Ta5d6ff, Ta5d6ff'Tff7b72.Td2a8ffjoinTb4b4b4(Te6edf3close_issuesTb4b4b4)Tffd700}Ta5d6ff"Tb4b4b4,
Tb4b4b4)
Tff7b72selfTff7b72.Td2a8ffdatabaseTff7b72.Td2a8ff_checkpoint_and_closeTb4b4b4(Tb4b4b4)
Tff7b72except Tf85149Exception Tff7b72as Te6edf3eTb4b4b4:
Tffa657printTb4b4b4(
Ta5d6fffTa5d6ff"Ta5d6ffError closing database during teardown for Tffd700{Tff7b72selfTff7b72.Td2a8ffidentity_hashTffd700}Ta5d6ff: Tffd700{Te6edf3eTffd700}Ta5d6ff"Tb4b4b4,
Tb4b4b4)

T8b949e# 2. Save integrity manifest AFTER closing to capture final stable state
Tff7b72if Tff7b72selfTff7b72.Td2a8ffintegrity_managerTb4b4b4:
Tff7b72selfTff7b72.Td2a8ffintegrity_managerTff7b72.Td2a8ffsave_manifestTb4b4b4(Tb4b4b4)
Tff7b72selfTff7b72.Td2a8ffdatabase Tff7b72= Tff7b72None

Tff7b72if Tff7b72selfTff7b72.Td2a8ffconfigTb4b4b4:
Tff7b72selfTff7b72.Td2a8ffconfig Tff7b72= Tff7b72None

Tff7b72if Tff7b72selfTff7b72.Td2a8ffintegrity_managerTb4b4b4:
Tff7b72selfTff7b72.Td2a8ffintegrity_manager Tff7b72= Tff7b72None

Tff7b72if Tff7b72selfTff7b72.Td2a8fflocal_lxmf_destinationTb4b4b4:
Tff7b72selfTff7b72.Td2a8fflocal_lxmf_destination Tff7b72= Tff7b72None

T8b949e# Final break of the largest cycle
Tff7b72selfTff7b72.Td2a8ffapp Tff7b72= Tff7b72None
Tff7b72selfTff7b72.Td2a8ffidentity Tff7b72= Tff7b72None

Tffa657printTb4b4b4(Ta5d6fffTa5d6ff"Ta5d6ffIdentity Context for Tffd700{Tff7b72selfTff7b72.Td2a8ffidentity_hashTffd700}Ta5d6ff torn down.Ta5d6ff"Tb4b4b4)


──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────